diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4afb8b9c13..f40b5cfd8c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,19 +1,14 @@ # Global owners, automatically request review when pull request is submitted -* @dfsek @solonovamax +* @dfsek @solonovamax @duplexsystem @astrsh @justaureus # Platforms -## dfsek wrote the majority of the platform impls -/platforms/bukkit/ @dfsek -/platforms/fabric/ @dfsek -/platforms/forge/ @dfsek -/platforms/sponge/ @dfsek -## solonovamax is working on the region generator (unless duplexsystem takes it over) -/platforms/region/ @solonovamax +/platforms/ @dfsek @solonovamax @duplexsystem @justaureus +/platforms/bukkit @dfsek @solonovamax @duplexsystem @justaureus @OakLoaf # Common -/common/ @dfsek @solonovamax +/common/ @dfsek @solonovamax @duplexsystem @astrsh # Gradle Stuff -## Most gradle stuff was written by solonovamax -/buildSrc/ @solonovamax -*.gradle.kts @solonovamax \ No newline at end of file +/buildSrc/ @dfsek @solonovamax @duplexsystem +*.gradle.kts @dfsek @solonovamax @duplexsystem +/gradle/ @dfsek @solonovamax @duplexsystem diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml new file mode 100644 index 0000000000..2117c7eee2 --- /dev/null +++ b/.github/workflows/gradle-build.yml @@ -0,0 +1,47 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle + +name: Gradle Build + +on: [ pull_request ] + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 + - name: Set up JDK 21 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 + with: + java-version: '21' + distribution: 'temurin' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6 + name: Build Terra + with: + # Specifies arguments for Gradle execution + # If arguments is missing or empty, then Gradle is not executed + arguments: build + # arguments can be multi-line for better readability + # arguments: | + # --no-paralell + # build + # -x test + # Gradle version to use for execution: + # wrapper (default), current, rc, nightly, release-nightly, or + # versions like 6.6 (see https://services.gradle.org/versions/all) + gradle-version: wrapper + # Properties are passed as -Pname=value + properties: | + kotlin.js.compiler=ir + kotlin.parallel.tasks.in.project=true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 63dda43600..8a964f70b2 100644 --- a/.gitignore +++ b/.gitignore @@ -249,3 +249,5 @@ nbdist/ platforms/**/run/** +#Vale Config File +**/.vale.ini diff --git a/build.gradle.kts b/build.gradle.kts index 73654719d7..968d1e3b72 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ preRelease(true) -versionProjects(":common:api", version("6.4.0")) -versionProjects(":common:implementation", version("6.4.0")) -versionProjects(":platforms", version("6.4.0")) +versionProjects(":common:api", version("6.5.1")) +versionProjects(":common:implementation", version("6.5.1")) +versionProjects(":platforms", version("6.5.1")) allprojects { @@ -15,6 +15,7 @@ allprojects { tasks.withType().configureEach { options.isFork = true options.isIncremental = true + options.release.set(21) } tasks.withType().configureEach { @@ -44,7 +45,7 @@ afterEvaluate { } project(":platforms:bukkit:common").configureDistribution() forSubProjects(":common:addons") { - apply(plugin = "com.github.johnrengelman.shadow") + apply(plugin = "com.gradleup.shadow") tasks.named("build") { finalizedBy(tasks.named("shadowJar")) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index eaec594a48..cec2d002d2 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -9,18 +9,18 @@ repositories { maven("https://repo.codemc.org/repository/maven-public") { name = "CodeMC" } - maven("https://papermc.io/repo/repository/maven-public/") { + maven("https://repo.papermc.io/repository/maven-public/") { name = "PaperMC" } } dependencies { //TODO Allow pulling from Versions.kt - implementation("com.github.johnrengelman", "shadow", "8.1.1") - implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.5.6") + implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1") + implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.7.2") - implementation("org.ow2.asm", "asm", "9.5") - implementation("org.ow2.asm", "asm-tree", "9.5") - implementation("com.dfsek.tectonic", "common", "4.2.0") - implementation("org.yaml", "snakeyaml", "2.2") + implementation("org.ow2.asm", "asm", "9.7") + implementation("org.ow2.asm", "asm-tree", "9.7") + implementation("com.dfsek.tectonic", "common", "4.2.1") + implementation("org.yaml", "snakeyaml", "2.3") } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/AddonConfig.kt b/buildSrc/src/main/kotlin/AddonConfig.kt index b4dda3bcaa..1880a7b0d2 100644 --- a/buildSrc/src/main/kotlin/AddonConfig.kt +++ b/buildSrc/src/main/kotlin/AddonConfig.kt @@ -18,7 +18,7 @@ fun Project.addonDir(dir: File, task: Task) { matchingAddons(dir) { it.name.startsWith("Terra-") // Assume everything that starts with Terra- is a core addon. }.forEach { - println("Deleting old addon: " + it.absolutePath) + logger.info("Deleting old addon: " + it.absolutePath) it.delete() } forSubProjects(":common:addons") { @@ -29,7 +29,7 @@ fun Project.addonDir(dir: File, task: Task) { val base = "${jar.archiveBaseName.get()}-${version}" - println("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") + logger.info("Copying addon ${jar.archiveFileName.get()} to ${target.absolutePath}. Base name: $base") jar.archiveFile.orNull?.asFile?.copyTo(target) } diff --git a/buildSrc/src/main/kotlin/CompilationConfig.kt b/buildSrc/src/main/kotlin/CompilationConfig.kt index 952b910918..f0d1e78294 100644 --- a/buildSrc/src/main/kotlin/CompilationConfig.kt +++ b/buildSrc/src/main/kotlin/CompilationConfig.kt @@ -22,8 +22,8 @@ fun Project.configureCompilation() { apply() configure { - sourceCompatibility = JavaVersion.VERSION_17 - targetCompatibility = JavaVersion.VERSION_17 + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } tasks.withType { diff --git a/buildSrc/src/main/kotlin/DependencyConfig.kt b/buildSrc/src/main/kotlin/DependencyConfig.kt index 82b3b206b1..0df8e29f20 100644 --- a/buildSrc/src/main/kotlin/DependencyConfig.kt +++ b/buildSrc/src/main/kotlin/DependencyConfig.kt @@ -36,7 +36,7 @@ fun Project.configureDependencies() { maven("https://repo.codemc.org/repository/maven-public") { name = "CodeMC" } - maven("https://papermc.io/repo/repository/maven-public/") { + maven("https://repo.papermc.io/repository/maven-public/") { name = "PaperMC" } maven("https://files.minecraftforge.net/maven/") { @@ -48,17 +48,17 @@ fun Project.configureDependencies() { maven("https://jitpack.io") { name = "JitPack" } - maven("https://nexuslite.gcnt.net/repos/other/") { - name = "GCNT" + maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { + name = "Sonatype Snapshots" } } dependencies { - testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0") - testImplementation("org.junit.jupiter:junit-jupiter-engine:5.7.0") - compileOnly("org.jetbrains:annotations:23.0.0") + testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit) + testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit) + compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations) - compileOnly("com.google.guava:guava:30.0-jre") - testImplementation("com.google.guava:guava:30.0-jre") + compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava) + testImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava) } } diff --git a/buildSrc/src/main/kotlin/DistributionConfig.kt b/buildSrc/src/main/kotlin/DistributionConfig.kt index 8c262e729b..0a1c2d060b 100644 --- a/buildSrc/src/main/kotlin/DistributionConfig.kt +++ b/buildSrc/src/main/kotlin/DistributionConfig.kt @@ -21,13 +21,14 @@ import kotlin.io.path.exists fun Project.configureDistribution() { - apply(plugin = "com.github.johnrengelman.shadow") + apply(plugin = "com.gradleup.shadow") val downloadDefaultPacks = tasks.create("downloadDefaultPacks") { group = "terra" doFirst { file("${buildDir}/resources/main/packs/").deleteRecursively() - val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/latest/default.zip") + val defaultPackUrl = + URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip") downloadPack(defaultPackUrl, project) } } @@ -53,7 +54,7 @@ fun Project.configureDistribution() { forSubProjects(":common:addons") { val jar = getJarTask() - println("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB") + logger.info("Packaging addon ${jar.archiveFileName.get()} to $dest. size: ${jar.archiveFile.get().asFile.length() / 1024}KB") val boot = if (extra.has("bootstrap") && extra.get("bootstrap") as Boolean) "bootstrap/" else "" val addonPath = fs.getPath("/addons/$boot${jar.archiveFileName.get()}") diff --git a/buildSrc/src/main/kotlin/Utils.kt b/buildSrc/src/main/kotlin/Utils.kt index b775871b09..679786788b 100644 --- a/buildSrc/src/main/kotlin/Utils.kt +++ b/buildSrc/src/main/kotlin/Utils.kt @@ -42,10 +42,10 @@ fun preRelease(preRelease: Boolean) { fun Project.versionProjects(project: String, version: String) { forSubProjects(project) { this.version = version - println("Setting version of $path to $version") + logger.info("Setting version of $path to $version") } project(project).version = version - println("Setting version of $project to $version") + logger.info("Setting version of $project to $version") } fun Project.version(version: String): String { diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index 18dbd85fef..1e48e716a6 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -1,26 +1,35 @@ object Versions { + object Terra { + const val overworldConfig = "v1.3.4" + } + object Libraries { const val tectonic = "4.2.1" const val paralithic = "0.7.1" const val strata = "1.3.2" - const val cloud = "1.8.4" + const val cloud = "2.0.0" + const val cloudPaper = "2.0.0-beta.10" + const val cloudFabric = "2.0.0-beta.9" - const val slf4j = "2.0.9" - const val log4j_slf4j_impl = "2.20.0" + const val caffeine = "3.1.8" + const val slf4j = "2.0.16" + object Internal { - const val shadow = "8.1.1" - const val apacheText = "1.10.0" - const val apacheIO = "2.14.0" - const val guava = "32.1.3-jre" - const val asm = "9.5" - const val snakeYml = "2.2" + const val shadow = "8.3.1" + const val apacheText = "1.12.0" + const val apacheIO = "2.16.1" + const val guava = "33.3.0-jre" + const val asm = "9.7" + const val snakeYml = "2.3" + const val jetBrainsAnnotations = "24.1.0" + const val junit = "5.11.0" } } object Fabric { - const val fabricAPI = "0.90.0+${Mod.minecraft}" + const val fabricAPI = "0.104.0+${Mod.minecraft}" } // // object Quilt { @@ -29,32 +38,30 @@ object Versions { // } object Mod { - const val mixin = "0.12.5+mixin.0.8.5" + const val mixin = "0.15.3+mixin.0.8.7" - const val minecraft = "1.20.2" - const val yarn = "$minecraft+build.4" - const val fabricLoader = "0.14.23" + const val minecraft = "1.21.1" + const val yarn = "$minecraft+build.3" + const val fabricLoader = "0.16.5" - const val architecuryLoom = "1.3.357" - const val architecturyPlugin = "3.4.146" - - const val loomVineflower = "1.11.0" - } - - object Forge { - const val forge = "${Mod.minecraft}-48.0.13" - const val burningwave = "12.63.0" + const val architecuryLoom = "1.7.413" + const val architecturyPlugin = "3.4.159" } +// +// object Forge { +// const val forge = "${Mod.minecraft}-48.0.13" +// const val burningwave = "12.63.0" +// } object Bukkit { - const val paper = "1.18.2-R0.1-SNAPSHOT" - const val paperLib = "1.0.5" - const val foliaLib = "0.2.5" - const val minecraft = "1.20.2" - const val reflectionRemapper = "0.1.0-SNAPSHOT" - const val paperDevBundle = "1.20.2-R0.1-SNAPSHOT" - const val runPaper = "2.2.0" - const val paperWeight = "1.5.6" + const val minecraft = "1.21.1" + const val paperBuild = "$minecraft-R0.1-20240917.151311-80" + const val paper = paperBuild + const val paperLib = "1.0.8" + const val reflectionRemapper = "0.1.1" + const val paperDevBundle = paperBuild + const val runPaper = "2.3.1" + const val paperWeight = "1.7.2" } // @@ -66,6 +73,6 @@ object Versions { // object CLI { const val nbt = "6.1" - const val logback = "1.4.11" + const val logback = "1.5.8" } } \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/com/dfsek/terra/tectonicdoc/GenerateDocsTask.kt b/buildSrc/src/main/kotlin/com/dfsek/terra/tectonicdoc/GenerateDocsTask.kt index 30f5153553..60977aee5c 100644 --- a/buildSrc/src/main/kotlin/com/dfsek/terra/tectonicdoc/GenerateDocsTask.kt +++ b/buildSrc/src/main/kotlin/com/dfsek/terra/tectonicdoc/GenerateDocsTask.kt @@ -82,7 +82,7 @@ abstract class GenerateDocsTask : DefaultTask() { } template.add(keyName.toString(), description.toString().ifBlank { - println("No description provided for field " + field.name + " in class " + name) + logger.info("No description provided for field " + field.name + " in class " + name) "*No description provided.*" }) } diff --git a/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/api/Extrusion.java b/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/api/Extrusion.java index 4c4ca972aa..c1d5f5524d 100644 --- a/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/api/Extrusion.java +++ b/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/api/Extrusion.java @@ -1,9 +1,9 @@ package com.dfsek.terra.addons.biome.extrusion.api; -import java.util.Collection; - import com.dfsek.terra.api.world.biome.Biome; +import java.util.Collection; + public interface Extrusion { Biome extrude(Biome original, int x, int y, int z, long seed); diff --git a/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/extrusions/ReplaceExtrusion.java b/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/extrusions/ReplaceExtrusion.java index daa1b12d92..26b1ec4bb8 100644 --- a/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/extrusions/ReplaceExtrusion.java +++ b/common/addons/biome-provider-extrusion/src/main/java/com/dfsek/terra/addons/biome/extrusion/extrusions/ReplaceExtrusion.java @@ -1,5 +1,9 @@ package com.dfsek.terra.addons.biome.extrusion.extrusions; +import java.util.Collection; +import java.util.function.Predicate; +import java.util.stream.Collectors; + import com.dfsek.terra.addons.biome.extrusion.api.Extrusion; import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome; import com.dfsek.terra.addons.biome.query.api.BiomeQueries; @@ -8,10 +12,6 @@ import com.dfsek.terra.api.util.collection.ProbabilityCollection; import com.dfsek.terra.api.world.biome.Biome; -import java.util.Collection; -import java.util.function.Predicate; -import java.util.stream.Collectors; - /** * Sets biomes at locations based on a sampler. diff --git a/common/addons/biome-provider-image-v2/src/main/java/com/dfsek/terra/addons/biome/image/v2/ImageBiomeProvider.java b/common/addons/biome-provider-image-v2/src/main/java/com/dfsek/terra/addons/biome/image/v2/ImageBiomeProvider.java index 8809410c53..073bea70e2 100644 --- a/common/addons/biome-provider-image-v2/src/main/java/com/dfsek/terra/addons/biome/image/v2/ImageBiomeProvider.java +++ b/common/addons/biome-provider-image-v2/src/main/java/com/dfsek/terra/addons/biome/image/v2/ImageBiomeProvider.java @@ -7,13 +7,13 @@ package com.dfsek.terra.addons.biome.image.v2; +import java.util.Optional; + import com.dfsek.terra.addons.image.colorsampler.ColorSampler; import com.dfsek.terra.addons.image.converter.ColorConverter; import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import java.util.Optional; - public class ImageBiomeProvider implements BiomeProvider { private final int resolution; diff --git a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/config/BiomePipelineTemplate.java b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/config/BiomePipelineTemplate.java index 937a1b7dfc..75ffb8d65a 100644 --- a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/config/BiomePipelineTemplate.java +++ b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/config/BiomePipelineTemplate.java @@ -29,7 +29,7 @@ public class BiomePipelineTemplate implements ObjectTemplate { @Default @Description(""" The resolution at which to sample biomes. - + Larger values are quadratically faster, but produce lower quality results. For example, a value of 3 would sample every 3 blocks.""") protected @Meta int resolution = 1; diff --git a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/pipeline/BiomeChunkImpl.java b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/pipeline/BiomeChunkImpl.java index e9fe9dbb22..78b0fe806f 100644 --- a/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/pipeline/BiomeChunkImpl.java +++ b/common/addons/biome-provider-pipeline-v2/src/main/java/com/dfsek/terra/addons/biome/pipeline/v2/pipeline/BiomeChunkImpl.java @@ -14,7 +14,8 @@ public class BiomeChunkImpl implements BiomeChunk { private final SeededVector worldOrigin; private final int chunkOriginArrayIndex; private final int worldCoordinateScale; - private PipelineBiome[][] biomes; + private final int size; + private PipelineBiome[] biomes; public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { @@ -22,14 +23,14 @@ public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex(); this.worldCoordinateScale = pipeline.getResolution(); - int size = pipeline.getArraySize(); + this.size = pipeline.getArraySize(); int expanderCount = pipeline.getExpanderCount(); int expansionsApplied = 0; // Allocate working arrays - this.biomes = new PipelineBiome[size][size]; - PipelineBiome[][] lookupArray = new PipelineBiome[size][size]; + this.biomes = new PipelineBiome[size * size]; + PipelineBiome[] lookupArray = new PipelineBiome[size * size]; // A second lookup array is required such that stage application doesn't affect lookups, otherwise application may cascade // Construct working grid @@ -43,7 +44,7 @@ public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { for(int gridZ = 0; gridZ < gridSize; gridZ++) { int xIndex = gridOrigin + gridX * gridInterval; int zIndex = gridOrigin + gridZ * gridInterval; - biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), + biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex), zIndexToWorldCoordinate(zIndex)); } } @@ -65,7 +66,7 @@ public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { // Cycle arrays, the previously populated array is swapped to be used for lookups, and the result of the stage application // overwrites the previous lookup array. This saves having to allocate a new array copy each time - PipelineBiome[][] tempArray = biomes; + PipelineBiome[] tempArray = biomes; biomes = lookupArray; lookupArray = tempArray; @@ -74,7 +75,8 @@ public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) { for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) { int xIndex = gridOrigin + gridX * gridInterval; int zIndex = gridOrigin + gridZ * gridInterval; - biomes[xIndex][zIndex] = stage.apply(new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray)); + biomes[(xIndex * size) + zIndex] = stage.apply( + new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray, size)); } } } @@ -133,7 +135,7 @@ private static int calculateGridInterval(int totalExpansions, int expansionsAppl public PipelineBiome get(int xInChunk, int zInChunk) { int xIndex = xInChunk + chunkOriginArrayIndex; int zIndex = zInChunk + chunkOriginArrayIndex; - return biomes[xIndex][zIndex]; + return biomes[(xIndex * size) + zIndex]; } private int xIndexToWorldCoordinate(int xIndex) { @@ -159,10 +161,11 @@ public static class ViewPoint { private final int gridZ; private final int xIndex; private final int zIndex; - private final PipelineBiome[][] lookupArray; + private final PipelineBiome[] lookupArray; + private final int size; private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex, - PipelineBiome[][] lookupArray) { + PipelineBiome[] lookupArray, int size) { this.chunk = chunk; this.gridInterval = gridInterval; this.gridX = gridX; @@ -170,13 +173,14 @@ private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, this.xIndex = xIndex; this.zIndex = zIndex; this.lookupArray = lookupArray; - this.biome = lookupArray[xIndex][zIndex]; + this.size = size; + this.biome = lookupArray[(this.xIndex * this.size) + this.zIndex]; } public PipelineBiome getRelativeBiome(int x, int z) { int lookupXIndex = this.xIndex + x * gridInterval; int lookupZIndex = this.zIndex + z * gridInterval; - return lookupArray[lookupXIndex][lookupZIndex]; + return lookupArray[(lookupXIndex * this.size) + lookupZIndex]; } public PipelineBiome getBiome() { diff --git a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomePipelineTemplate.java b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomePipelineTemplate.java index 491f019baf..1566de5245 100644 --- a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomePipelineTemplate.java +++ b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomePipelineTemplate.java @@ -28,7 +28,7 @@ public class BiomePipelineTemplate extends BiomeProviderTemplate { @Description(""" The initial size of biome chunks. This value must be at least 2. This is not the final size of biome chunks. Final chunks will be much larger. - + It is recommended to keep biome chunks' final size in the range of [50, 300] to prevent performance issues. To calculate the size of biome chunks, simply take initial-size and for each expand stage, multiply the running value by 2 diff --git a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomeProviderTemplate.java b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomeProviderTemplate.java index f42fd7c209..93f84e80a4 100644 --- a/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomeProviderTemplate.java +++ b/common/addons/biome-provider-pipeline/src/main/java/com/dfsek/terra/addons/biome/pipeline/config/BiomeProviderTemplate.java @@ -22,7 +22,7 @@ public abstract class BiomeProviderTemplate implements ObjectTemplate("shadowJar") { + relocate("net.jafama", "com.dfsek.terra.addons.chunkgenerator.lib.jafama") + relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.chunkgenerator.lib.paralithic") +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java new file mode 100644 index 0000000000..4a22c40241 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/LayeredChunkGeneratorAddon.java @@ -0,0 +1,172 @@ +package com.dfsek.terra.addons.chunkgenerator; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Supplier; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPalettePackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPredicatePackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerResolverPackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerSamplerPackConfigTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomeDefinedLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.DotProductLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.PlatformAirLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.palette.SimpleLayerPaletteTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.AdjacentPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.SimplePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CubePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CuboidPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.SphericalPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.DifferencePointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.ExpressionFilterPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.IntersectionPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.UnionPointSetTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.BelowLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.RangeLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerListLayerPredicateTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.resolve.PaletteLayerResolverTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.resolve.PredicateLayerResolverTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.sampler.BiomeDefinedLayerSamplerTemplate; +import com.dfsek.terra.addons.chunkgenerator.config.sampler.SimpleLayerSamplerTemplate; +import com.dfsek.terra.addons.chunkgenerator.generation.LayeredChunkGenerator; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.manifest.api.AddonInitializer; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.event.functional.FunctionalEventHandler; +import com.dfsek.terra.api.inject.annotations.Inject; +import com.dfsek.terra.api.registry.CheckedRegistry; +import com.dfsek.terra.api.util.reflection.TypeKey; +import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider; + + +public class LayeredChunkGeneratorAddon implements AddonInitializer { + + private static final Logger logger = LoggerFactory.getLogger(LayeredChunkGenerator.class); + + public static final TypeKey>> POINT_SET_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_SAMPLER_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_SAMPLER_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_PALETTE_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_PALETTE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_PREDICATE_TYPE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey> LAYER_PREDICATE_TOKEN = new TypeKey<>() { + }; + + public static final TypeKey>> LAYER_RESOLVER_TYPE_TOKEN = new TypeKey<>() { + }; + + @Inject + private Platform platform; + + @Inject + private BaseAddon addon; + + @Override + public void initialize() { + + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(addon, ConfigPackPreLoadEvent.class) + .priority(1000) + .then(event -> { + event.getPack().applyLoader(RelationalOperator.class, + (type, o, loader, depthTracker) -> RelationalOperator.valueOf((String) o)); + + CheckedRegistry>> pointSetTypeRegistry = event.getPack().getOrCreateRegistry( + POINT_SET_TYPE_TOKEN); + pointSetTypeRegistry.register(addon.key("LIST"), SimplePointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("ADJACENT"), AdjacentPointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("SPHERE"), SphericalPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("CUBOID"), CuboidPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("CUBE"), CubePointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("UNION"), UnionPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("INTERSECTION"), IntersectionPointSetTemplate::new); + pointSetTypeRegistry.register(addon.key("DIFFERENCE"), DifferencePointSetTemplate::new); + + pointSetTypeRegistry.register(addon.key("EXPRESSION"), ExpressionFilterPointSetTemplate::new); + }) + .then(event -> { + CheckedRegistry>> samplerTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TYPE_TOKEN); + CheckedRegistry> samplerRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TOKEN); + samplerTypeRegistry.register(addon.key("SIMPLE"), SimpleLayerSamplerTemplate::new); + samplerTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerSamplerTemplate::new); + + event.loadTemplate(new LayerSamplerPackConfigTemplate()).getSamplers().forEach((key, sampler) -> { + samplerRegistry.register(addon.key(key), new InstanceWrapper<>(sampler)); + }); + }) + .then(event -> { + CheckedRegistry>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN); + predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new); + predicateTypeRegistry.register(addon.key("SAMPLER_POINTS"), SamplerListLayerPredicateTemplate::new); + + CheckedRegistry> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN); + event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> { + predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate)); + }); + }) + .then(event -> { + CheckedRegistry>> paletteTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TYPE_TOKEN); + paletteTypeRegistry.register(addon.key("PALETTE"), SimpleLayerPaletteTemplate::new); + paletteTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerPaletteTemplate::new); + paletteTypeRegistry.register(addon.key("AIR"), () -> new PlatformAirLayerPaletteTemplate(platform)); + paletteTypeRegistry.register(addon.key("SURFACE_NORMAL"), DotProductLayerPaletteTemplate::new); + + event.getPack().applyLoader(LayerPalette.Group.class, new LayerPalette.Group.Loader(event.getPack())); + + CheckedRegistry> paletteRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TOKEN); + event.loadTemplate(new LayerPalettePackConfigTemplate()).getPalettes().forEach((key, palette) -> { + paletteRegistry.register(addon.key(key), new InstanceWrapper<>(palette)); + }); + }) + .then(event -> { + CheckedRegistry>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN); + resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new); + resolverTypeRegistry.register(addon.key("LAYER"), PaletteLayerResolverTemplate::new); + LayerResolver resolver = event.loadTemplate(new LayerResolverPackConfigTemplate()).getResolver(); + + event.getPack() + .getOrCreateRegistry(ChunkGeneratorProvider.class) + .register(addon.key("LAYERED"), + pack -> new LayeredChunkGenerator(platform, resolver)); + }) + .failThrough(); + + platform.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(addon, ConfigurationLoadEvent.class) + .priority(1000) + .then(BiomeDefinedLayerPalette.injectLayerPalettes) + .then(BiomeDefinedLayerSampler.injectLayerSamplers); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java new file mode 100644 index 0000000000..bce83f62b3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPalette.java @@ -0,0 +1,72 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.HashMap; +import java.util.Map; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public abstract class LayerPalette { + + private final Group group; + + private final boolean resetsGroup; + + protected LayerPalette(Group group, boolean resetsGroup) { + this.group = group; + this.resetsGroup = resetsGroup; + } + + public abstract Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); + + public final Group getGroup() { + return group; + } + + public final boolean resetsGroup() { + return resetsGroup; + } + + public static class Group { + + public static Group NO_GROUP = new Group(); + + private Group() {} + + public static Group get(String string, ConfigPack pack) { + if (!pack.getContext().has(Holder.class)) { + pack.getContext().put(new Holder(new HashMap<>())); + } + return pack.getContext().get(Holder.class).groups.computeIfAbsent(string, s -> new Group()); + } + + private record Holder(Map groups) implements Properties {} + + public static class Loader implements TypeLoader { + + private final ConfigPack pack; + + public Loader(ConfigPack pack) { + this.pack = pack; + } + + @Override + public Group load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + String groupName = (String) o; + return Group.get(groupName, pack); + } + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java new file mode 100644 index 0000000000..95c09b7989 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerPredicate.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerPredicate { + boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java new file mode 100644 index 0000000000..5d0efbd069 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerResolver.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerResolver { + LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java new file mode 100644 index 0000000000..5a782494e6 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/api/LayerSampler.java @@ -0,0 +1,9 @@ +package com.dfsek.terra.addons.chunkgenerator.api; + +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public interface LayerSampler { + double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java new file mode 100644 index 0000000000..8485ec8366 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPalettePackConfigTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerPalettePackConfigTemplate implements ConfigTemplate { + + @Value("generation.layers") + private @Meta Map palettes; + + public Map getPalettes() { + return palettes; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java new file mode 100644 index 0000000000..cf4bb2172b --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerPredicatePackConfigTemplate.java @@ -0,0 +1,24 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerPredicatePackConfigTemplate implements ConfigTemplate { + + @Value("generation.tests") + @Default + private @Meta Map predicates = new LinkedHashMap<>(); + + public Map getPredicates() { + return predicates; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java new file mode 100644 index 0000000000..71e8363afd --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerResolverPackConfigTemplate.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerResolverPackConfigTemplate implements ConfigTemplate { + + @Value("generation.resolver") + private @Meta LayerResolver resolver; + + public LayerResolver getResolver() { + return resolver; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java new file mode 100644 index 0000000000..e811314007 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pack/LayerSamplerPackConfigTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pack; + +import com.dfsek.tectonic.api.config.template.ConfigTemplate; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.api.config.meta.Meta; + + +public class LayerSamplerPackConfigTemplate implements ConfigTemplate { + + @Value("generation.samplers") + private @Meta Map samplers; + + public Map getSamplers() { + return samplers; + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java new file mode 100644 index 0000000000..f04d81ffd7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomeDefinedLayerPaletteTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class BiomeDefinedLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("default") + @Default + private Palette defaultPalette = null; + + @Override + public LayerPalette get() { + return new BiomeDefinedLayerPalette(group, resetsGroup, defaultPalette); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java new file mode 100644 index 0000000000..6d8fed140d --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/DotProductLayerPaletteTemplate.java @@ -0,0 +1,44 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import java.util.HashMap; +import java.util.Map; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.DotProductLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet; +import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class DotProductLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("normal.approximation-points") + @Default + private PointSet normalApproximationPoints = new AdjacentPointSet(); + + @Value("normal.direction") + @Default + private Vector3 direction = Vector3.of(0, 1, 0); + + @Value("normal.sampler") + private InstanceWrapper sampler; + + @Value("palettes") + private Map palettes; + + @Override + public LayerPalette get() { + Map paletteMap = new HashMap<>(); + palettes.forEach((s, p) -> { + paletteMap.put(Double.parseDouble(s), p); + }); + return new DotProductLayerPalette(group, resetsGroup, normalApproximationPoints, new DoubleNavigableHolder<>(paletteMap), sampler.get(), direction); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java new file mode 100644 index 0000000000..e925c7ef86 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/LayerPaletteTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; + + +public abstract class LayerPaletteTemplate implements ObjectTemplate { + + @Value("group") + @Default + protected LayerPalette.Group group = LayerPalette.Group.NO_GROUP; + + @Value("resets-group") + @Default + protected boolean resetsGroup = false; + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java new file mode 100644 index 0000000000..00e4feadf3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/PlatformAirLayerPaletteTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette; +import com.dfsek.terra.addons.chunkgenerator.palette.SingletonPalette; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; + + +public class PlatformAirLayerPaletteTemplate extends LayerPaletteTemplate { + + private BlockState air; + + public PlatformAirLayerPaletteTemplate(Platform platform) { + this.air = platform.getWorldHandle().air(); + } + + @Override + public LayerPalette get() { + return new SimpleLayerPalette(group, resetsGroup, new SingletonPalette(air)); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java new file mode 100644 index 0000000000..43432b43cb --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/SimpleLayerPaletteTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.palette; + +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class SimpleLayerPaletteTemplate extends LayerPaletteTemplate { + + @Value("palette") + private Palette palette; + + @Override + public LayerPalette get() { + return new SimpleLayerPalette(group, resetsGroup, palette); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java new file mode 100644 index 0000000000..8379cce2e9 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/AdjacentPointSetTemplate.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet; + + +public class AdjacentPointSetTemplate implements ObjectTemplate { + + @Override + public PointSet get() { + return new AdjacentPointSet(); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java new file mode 100644 index 0000000000..b8104cf07b --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/SimplePointSetTemplate.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.Set; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.SimplePointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public class SimplePointSetTemplate implements ObjectTemplate { + + @Value("points") + private Set list; + + @Override + public PointSet get() { + return new SimplePointSet(list); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java new file mode 100644 index 0000000000..340dd1985d --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CubePointSetTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet; + + +public class CubePointSetTemplate implements ObjectTemplate { + + @Value("size") + private int size; + + @Override + public PointSet get() { + return new CuboidPointSet(-size, -size, -size, size, size, size); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java new file mode 100644 index 0000000000..457548a2ae --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/CuboidPointSetTemplate.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet; + + +public class CuboidPointSetTemplate implements ObjectTemplate { + + @Value("size.x") + private int xSize; + + @Value("size.y") + private int ySize; + + @Value("size.z") + private int zSize; + + @Override + public PointSet get() { + return new CuboidPointSet(-xSize, -ySize, -zSize, xSize, ySize, zSize); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java new file mode 100644 index 0000000000..b822f119f7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/generative/geometric/SphericalPointSetTemplate.java @@ -0,0 +1,19 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.SphericalPointSet; + + +public class SphericalPointSetTemplate implements ObjectTemplate { + + @Value("radius") + private double radius; + + @Override + public PointSet get() { + return new SphericalPointSet(radius); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java new file mode 100644 index 0000000000..5a381513e2 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/DifferencePointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.DifferencePointSet; + + +public class DifferencePointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List set; + + @Override + public PointSet get() { + return new DifferencePointSet(set); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java new file mode 100644 index 0000000000..ef30b76658 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/ExpressionFilterPointSetTemplate.java @@ -0,0 +1,27 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.paralithic.eval.tokenizer.ParseException; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.ExpressionFilterPointSet; + + +public class ExpressionFilterPointSetTemplate implements ObjectTemplate { + + @Value("point-set") + private PointSet set; + + @Value("expression") + private String expression; + + @Override + public PointSet get() { + try { + return new ExpressionFilterPointSet(set, expression); + } catch(ParseException e) { + throw new RuntimeException("Failed to parse expression.", e); + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java new file mode 100644 index 0000000000..d860287e61 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/IntersectionPointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.IntersectionPointSet; + + +public class IntersectionPointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List sets; + + @Override + public PointSet get() { + return new IntersectionPointSet(sets); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java new file mode 100644 index 0000000000..2a4ba8ac97 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/pointset/operative/UnionPointSetTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.List; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.UnionPointSet; + + +public class UnionPointSetTemplate implements ObjectTemplate { + + @Value("point-sets") + private List sets; + + @Override + public PointSet get() { + return new UnionPointSet(sets); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java new file mode 100644 index 0000000000..b6ec6d6c11 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/BelowLayerPredicateTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.BelowLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.config.meta.Meta; + + +public class BelowLayerPredicateTemplate implements ObjectTemplate { + + @Value("y") + private @Meta int y; + + @Override + public LayerPredicate get() { + return new BelowLayerPredicate(y); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java new file mode 100644 index 0000000000..fec9f8a77a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/RangeLayerPredicateTemplate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.RangeLayerPredicate; +import com.dfsek.terra.api.util.Range; + + +public class RangeLayerPredicateTemplate implements ObjectTemplate { + + @Value("range") + private Range range; + + @Override + public LayerPredicate get() { + return new RangeLayerPredicate(range); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java new file mode 100644 index 0000000000..4477acaedc --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerLayerPredicateTemplate.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.api.config.meta.Meta; + + +public class SamplerLayerPredicateTemplate implements ObjectTemplate { + + @Value("sampler") + private @Meta InstanceWrapper sampler; + + @Value("threshold") + @Default + private double threshold = 0; + + @Value("operator") + @Default + private RelationalOperator operator = RelationalOperator.GreaterThan; + + @Override + public LayerPredicate get() { + return new SamplerLayerPredicate(sampler.get(), operator, threshold); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java new file mode 100644 index 0000000000..06f814f738 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/predicate/SamplerListLayerPredicateTemplate.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.addons.chunkgenerator.config.predicate; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerListLayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.config.meta.Meta; + + +public class SamplerListLayerPredicateTemplate implements ObjectTemplate { + + @Value("sampler") + private @Meta InstanceWrapper sampler; + + @Value("point-set") + private PointSet points; + + @Value("threshold") + @Default + private double defaultThreshold = 0; + + @Value("operator") + @Default + private RelationalOperator defaultOperator = RelationalOperator.GreaterThan; + + @Override + public LayerPredicate get() { + return new SamplerListLayerPredicate(sampler.get(), defaultThreshold, defaultOperator, points); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java new file mode 100644 index 0000000000..de1474dbff --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PaletteLayerResolverTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.resolve; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PaletteLayerResolver; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; + + +public class PaletteLayerResolverTemplate implements ObjectTemplate { + + @Value("layer") + private InstanceWrapper palette; + + @Override + public LayerResolver get() { + return new PaletteLayerResolver(palette.get()); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java new file mode 100644 index 0000000000..b143a9c839 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/resolve/PredicateLayerResolverTemplate.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.addons.chunkgenerator.config.resolve; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PredicateLayerResolver; +import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper; +import com.dfsek.terra.api.config.meta.Meta; + + +public class PredicateLayerResolverTemplate implements ObjectTemplate { + + @Value("if") + private @Meta InstanceWrapper predicate; + + @Value("then") + private @Meta LayerResolver trueResolver; + + @Value("else") + private @Meta LayerResolver falseResolver; + + @Override + public PredicateLayerResolver get() { + return new PredicateLayerResolver(predicate.get(), trueResolver, falseResolver); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java new file mode 100644 index 0000000000..4fb7965c30 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/BiomeDefinedLayerSamplerTemplate.java @@ -0,0 +1,23 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class BiomeDefinedLayerSamplerTemplate implements ObjectTemplate { + + @Value("default") + @Default + private @Meta NoiseSampler defaultSampler = null; + + @Override + public LayerSampler get() { + return new BiomeDefinedLayerSampler(defaultSampler); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/SimpleLayerSamplerTemplate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/SimpleLayerSamplerTemplate.java new file mode 100644 index 0000000000..46bd115d63 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/sampler/SimpleLayerSamplerTemplate.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.config.sampler; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.layer.sampler.SimpleLayerSampler; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class SimpleLayerSamplerTemplate implements ObjectTemplate { + + @Value("sampler") + private @Meta NoiseSampler sampler; + + @Override + public LayerSampler get() { + return new SimpleLayerSampler(sampler); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java new file mode 100644 index 0000000000..ae096ca6f7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/LayeredChunkGenerator.java @@ -0,0 +1,90 @@ +package com.dfsek.terra.addons.chunkgenerator.generation; + +import org.jetbrains.annotations.NotNull; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.util.Column; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; +import com.dfsek.terra.api.world.chunk.generation.ProtoChunk; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class LayeredChunkGenerator implements ChunkGenerator { + + private final Platform platform; + private final LayerResolver resolver; + + public LayeredChunkGenerator(Platform platform, LayerResolver resolver) { + this.platform = platform; + this.resolver = resolver; + } + + @Override + public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world, @NotNull BiomeProvider biomeProvider, + int chunkX, int chunkZ) { + + platform.getProfiler().push("chunk_base_layered"); + + int xOrig = (chunkX << 4); + int zOrig = (chunkZ << 4); + long seed = world.getSeed(); + + for(int x = 0; x < 16; x++) { + for(int z = 0; z < 16; z++) { + + int cx = xOrig + x; + int cz = zOrig + z; + int paletteLevel = 0; + LayerPalette previousLayerPalette = null; + Column biomeColumn = biomeProvider.getColumn(cx, cz, world); + + for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) { + + Biome biome = biomeColumn.get(y); + + LayerPalette layerPalette = resolver.resolve(cx, y, cz, world, biomeProvider); + + if (previousLayerPalette == layerPalette) { + paletteLevel++; + } else if (layerPalette.resetsGroup()) { + paletteLevel = 0; + } else if (previousLayerPalette != null && layerPalette.getGroup() == previousLayerPalette.getGroup()) { + paletteLevel++; + } else { + paletteLevel = 0; + } + previousLayerPalette = layerPalette; + + chunk.setBlock(cx, y, cz, layerPalette.get(cx, y, cz, world, biomeProvider) + .get(paletteLevel, cx, y, cz, seed)); + } + } + } + + platform.getProfiler().pop("chunk_base_layered"); + } + + @Override + public BlockState getBlock(WorldProperties world, int x, int y, int z, BiomeProvider biomeProvider) { + long seed = world.getSeed(); + Biome biome = biomeProvider.getBiome(x, y, z, seed); + int layer = 0; // Default to layer 0 for now + return resolver.resolve(x, y, z, world, biomeProvider) + .get(x, y, z, world, biomeProvider) + .get(layer, x, y, z, seed); + } + + @Override + public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + long seed = world.getSeed(); + Biome biome = biomeProvider.getBiome(x, y, z, seed); + return resolver.resolve(x, y, z, world, biomeProvider) + .get(x, y, z, world, biomeProvider); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java new file mode 100644 index 0000000000..2eb965f031 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/BiomeDefinedLayerPalette.java @@ -0,0 +1,70 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate; +import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BiomeDefinedLayerPalette extends LayerPalette { + + private final Palette defaultPalette; + + public BiomeDefinedLayerPalette(Group group, boolean resetsGroup, Palette defaultPalette) { + super(group, resetsGroup); + this.defaultPalette = defaultPalette; + } + + @Override + public Palette get(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return biomeProvider.getBiome(x, y, z, worldProperties.getSeed()).getContext().get(BiomeLayerPalettes.class).palettes().get(this); + } + + public Optional getDefaultPalette() { + return Optional.ofNullable(defaultPalette); + } + + public static Consumer injectLayerPalettes = event -> { + if(event.is(Biome.class)) { + + Map paletteFields = new HashMap<>(); + DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder(); + + event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_PALETTE_TOKEN).forEach((registryKey, registryEntry) -> { + LayerPalette layerPalette = registryEntry.get(); + // Add template value for each BiomeDefinedLayerPalette + if (layerPalette instanceof BiomeDefinedLayerPalette biomeLayerPalette) { + String id = registryKey.getID(); + String fieldName = id + "LayerPalette"; + paletteFields.put(biomeLayerPalette, fieldName); + DynamicValue.Builder value = DynamicValue.builder("generation.layers." + id, Palette.class); + biomeLayerPalette.getDefaultPalette().ifPresent(value::setDefault); + templateBuilder.value(fieldName, value.build()); + } + }); + + DynamicTemplate layerPaletteBiomeTemplate = event.load(templateBuilder.build()); + + Map paletteMap = paletteFields.entrySet().stream().collect( + Collectors.toMap(Entry::getKey, entry -> layerPaletteBiomeTemplate.get(entry.getValue(), Palette.class))); + event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerPalettes(paletteMap)); + } + }; + + public record BiomeLayerPalettes(Map palettes) implements Properties { + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java new file mode 100644 index 0000000000..8da5d5f7b5 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/DotProductLayerPalette.java @@ -0,0 +1,43 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.Vector3Int; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class DotProductLayerPalette extends LayerPalette { + + private static final Logger logger = LoggerFactory.getLogger(DotProductLayerPalette.class); + private final DoubleNavigableHolder palettes; + private final Vector3Int[] samplePoints; + private final LayerSampler sampler; + private final Vector3 direction; + + public DotProductLayerPalette(Group group, boolean resetsGroup, + PointSet points, DoubleNavigableHolder palettes, LayerSampler sampler, Vector3 direction) { + super(group, resetsGroup); + this.palettes = palettes; + this.sampler = sampler; + this.direction = direction; + this.samplePoints = points.toArray(); + } + + @Override + public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + Vector3.Mutable surfaceNormalApproximation = Vector3.Mutable.of(0, 0, 0); + for(Vector3Int point : samplePoints) { + double scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ(), world, biomeProvider); + surfaceNormalApproximation.add(point.toVector3Mutable().multiply(scalar)); + } + return palettes.get(direction.dot(surfaceNormalApproximation.normalize())); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java new file mode 100644 index 0000000000..ff98582302 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/palette/SimpleLayerPalette.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.palette; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SimpleLayerPalette extends LayerPalette { + + private final Palette palette; + + public SimpleLayerPalette(Group group, boolean resetsGroup, Palette palette) { + super(group, resetsGroup); + this.palette = palette; + } + + @Override + public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return palette; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java new file mode 100644 index 0000000000..2f5f4faf38 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/BelowLayerPredicate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BelowLayerPredicate implements LayerPredicate { + + private final int y; + + public BelowLayerPredicate(int y) { + this.y = y; + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return y < this.y; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java new file mode 100644 index 0000000000..c7d108a118 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/RangeLayerPredicate.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.api.util.Range; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class RangeLayerPredicate implements LayerPredicate { + + private final Range range; + + public RangeLayerPredicate(Range range) { + this.range = range; + } + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return range.isInRange(y); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java new file mode 100644 index 0000000000..7a5a5d33a8 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerLayerPredicate.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SamplerLayerPredicate implements LayerPredicate { + + private final LayerSampler sampler; + + private final double threshold; + + private final RelationalOperator operator; + + public SamplerLayerPredicate(LayerSampler sampler, RelationalOperator operator, double threshold) { + this.sampler = sampler; + this.operator = operator; + this.threshold = threshold; + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + return operator.test(sampler.sample(x, y, z, worldProperties, biomeProvider), threshold); + } + +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java new file mode 100644 index 0000000000..a0796be8c7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/predicate/SamplerListLayerPredicate.java @@ -0,0 +1,33 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.predicate; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator; +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SamplerListLayerPredicate implements LayerPredicate { + + private final Vector3Int[] points; + private final RelationalOperator operator; + private final LayerSampler sampler; + private final double threshold; + + public SamplerListLayerPredicate(LayerSampler sampler, double threshold, RelationalOperator operator, PointSet points) { + this.sampler = sampler; + this.threshold = threshold; + this.operator = operator; + this.points = points.toArray(); + } + + @Override + public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) { + for (Vector3Int point : points) { + if (operator.test(sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ(), worldProperties, biomeProvider), threshold)) return true; + } + return false; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java new file mode 100644 index 0000000000..8c16970e76 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PaletteLayerResolver.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.resolve; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class PaletteLayerResolver implements LayerResolver { + + private final LayerPalette palette; + + public PaletteLayerResolver(LayerPalette palette) { + this.palette = palette; + } + + @Override + public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return palette; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java new file mode 100644 index 0000000000..27bc0f363a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/resolve/PredicateLayerResolver.java @@ -0,0 +1,28 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.resolve; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette; +import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate; +import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class PredicateLayerResolver implements LayerResolver { + + private final LayerPredicate predicate; + + private final LayerResolver trueResolver; + + private final LayerResolver falseResolver; + + public PredicateLayerResolver(LayerPredicate predicate, LayerResolver trueResolver, LayerResolver falseResolver) { + this.predicate = predicate; + this.trueResolver = trueResolver; + this.falseResolver = falseResolver; + } + + @Override + public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return predicate.test(x, y, z, world, biomeProvider) ? trueResolver.resolve(x, y, z, world, biomeProvider) : falseResolver.resolve(x, y, z, world, biomeProvider); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java new file mode 100644 index 0000000000..804acdf0df --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/BiomeDefinedLayerSampler.java @@ -0,0 +1,75 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler; + +import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate; +import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue; + +import javax.annotation.Nullable; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon; +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.properties.Properties; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class BiomeDefinedLayerSampler implements LayerSampler { + + private final NoiseSampler defaultSampler; + + public BiomeDefinedLayerSampler(@Nullable NoiseSampler defaultSampler) { + this.defaultSampler = defaultSampler; + } + + @Override + public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return biomeProvider.getBiome(x, y, z, world.getSeed()) + .getContext() + .get(BiomeLayerSamplers.class) + .samplers() + .get(this) + .noise(world.getSeed(), x, y, z); + } + + private Optional getDefaultSampler() { + return Optional.ofNullable(defaultSampler); + } + + public static Consumer injectLayerSamplers = event -> { + if(event.is(Biome.class)) { + + Map samplerFields = new HashMap<>(); + DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder(); + + event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_SAMPLER_TOKEN).forEach((registryKey, registryEntry) -> { + LayerSampler layerSampler = registryEntry.get(); + + if (layerSampler instanceof BiomeDefinedLayerSampler biomeLayerSampler) { + String id = registryKey.getID(); + String fieldName = id + "LayerSampler"; + samplerFields.put(biomeLayerSampler, fieldName); + DynamicValue.Builder value = DynamicValue.builder("generation.samplers." + id, NoiseSampler.class); + biomeLayerSampler.getDefaultSampler().ifPresent(value::setDefault); + templateBuilder.value(fieldName, value.build()); + } + }); + + DynamicTemplate layerSamplerBiomeTemplate = event.load(templateBuilder.build()); + + Map samplerMap = samplerFields.entrySet().stream().collect( + Collectors.toMap(Entry::getKey, entry -> layerSamplerBiomeTemplate.get(entry.getValue(), NoiseSampler.class))); + event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerSamplers(samplerMap)); + } + }; + + public record BiomeLayerSamplers(Map samplers) implements Properties { + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/SimpleLayerSampler.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/SimpleLayerSampler.java new file mode 100644 index 0000000000..40177b0b22 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/layer/sampler/SimpleLayerSampler.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.addons.chunkgenerator.layer.sampler; + +import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler; +import com.dfsek.terra.api.noise.NoiseSampler; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class SimpleLayerSampler implements LayerSampler { + + private NoiseSampler sampler; + + public SimpleLayerSampler(NoiseSampler sampler) { + this.sampler = sampler; + } + + @Override + public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { + return sampler.noise(world.getSeed(), x, y, z); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java new file mode 100644 index 0000000000..a36b526bc0 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/RelationalOperator.java @@ -0,0 +1,45 @@ +package com.dfsek.terra.addons.chunkgenerator.math; + +import com.dfsek.terra.addons.chunkgenerator.util.DoubleBiPredicate; + + +public enum RelationalOperator implements DoubleBiPredicate { + GreaterThan { + @Override + public boolean test(double a, double b) { + return a > b; + } + }, + GreaterThanOrEqual { + @Override + public boolean test(double a, double b) { + return a >= b; + } + }, + LessThan { + @Override + public boolean test(double a, double b) { + return a < b; + } + }, + LessThanOrEqual { + @Override + public boolean test(double a, double b) { + return a <= b; + } + }, + Equals { + @Override + public boolean test(double a, double b) { + return a == b; + } + }, + NotEquals { + @Override + public boolean test(double a, double b) { + return a != b; + } + }; + + public abstract boolean test(double a, double b); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java new file mode 100644 index 0000000000..16466fd6ac --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/PointSet.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset; + +import java.util.function.Supplier; +import java.util.stream.Stream; + +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public interface PointSet extends Supplier> { + + default Vector3Int[] toArray() { + return this.get().distinct().toArray(Vector3Int[]::new); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java new file mode 100644 index 0000000000..e6788a455a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/AdjacentPointSet.java @@ -0,0 +1,20 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + +public class AdjacentPointSet implements PointSet { + @Override + public Stream get() { + return Stream.of( + Vector3Int.of(0, 0, -1), + Vector3Int.of(0, 0, 1), + Vector3Int.of(0, -1, 0), + Vector3Int.of(0, 1, 0), + Vector3Int.of(-1, 0, 0), + Vector3Int.of(1, 0, 0) + ); + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java new file mode 100644 index 0000000000..e1e50bdc08 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/SimplePointSet.java @@ -0,0 +1,22 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative; + +import java.util.Set; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public class SimplePointSet implements PointSet { + + private final Stream points; + + public SimplePointSet(Set points) { + this.points = points.stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java new file mode 100644 index 0000000000..08e8d746f4 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/CuboidPointSet.java @@ -0,0 +1,31 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public class CuboidPointSet implements PointSet { + + private final Stream points; + + public CuboidPointSet(int x1, int y1, int z1, int x2, int y2, int z2) { + Set points = new HashSet<>(); + for (int x = x1; x <= x2; x = x + 1) { + for (int y = y1; y <= y2; y = y + 1) { + for (int z = z1; z <= z2; z = z + 1) { + points.add(Vector3Int.of(x, y, z)); + } + } + } + this.points = points.stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java new file mode 100644 index 0000000000..5621fadef9 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/generative/geometric/SphericalPointSet.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric; + +import net.jafama.FastMath; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public class SphericalPointSet implements PointSet { + + private final Stream points; + + public SphericalPointSet(double radius) { + Stream.Builder streamBuilder = Stream.builder(); + int roundedRadius = FastMath.ceilToInt(radius); + for(int x = -roundedRadius; x <= roundedRadius; x++) { + for(int y = -roundedRadius; y <= roundedRadius; y++) { + for(int z = -roundedRadius; z <= roundedRadius; z++) { + Vector3Int pos = Vector3Int.of(x, y, z); + double length = pos.toVector3().length(); + if (length == 0) continue; + if (length > radius) continue; + streamBuilder.add(pos); + } + } + } + this.points = streamBuilder.build(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java new file mode 100644 index 0000000000..ed958bf1a7 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/DifferencePointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + +public class DifferencePointSet implements PointSet { + + private final Stream points; + + public DifferencePointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::difference).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java new file mode 100644 index 0000000000..8906446e99 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/ExpressionFilterPointSet.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.dfsek.paralithic.Expression; +import com.dfsek.paralithic.eval.parser.Parser; +import com.dfsek.paralithic.eval.parser.Scope; +import com.dfsek.paralithic.eval.tokenizer.ParseException; + +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + + +public class ExpressionFilterPointSet implements PointSet { + + private final Stream points; + + public ExpressionFilterPointSet(PointSet set, String eq) throws ParseException { + Parser parser = new Parser(); + Scope scope = new Scope(); + scope.addInvocationVariable("x"); + scope.addInvocationVariable("y"); + scope.addInvocationVariable("z"); + Expression expression = parser.parse(eq, scope); + this.points = set.get().filter(v -> expression.evaluate(v.getX(), v.getY(), v.getZ()) == 1); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java new file mode 100644 index 0000000000..0dbe0c498c --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/IntersectionPointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + +public class IntersectionPointSet implements PointSet { + + private final Stream points; + + public IntersectionPointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::intersection).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java new file mode 100644 index 0000000000..bd01c1c68f --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/math/pointset/operative/UnionPointSet.java @@ -0,0 +1,29 @@ +package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative; + +import com.google.common.collect.Sets; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet; +import com.dfsek.terra.api.util.vector.Vector3Int; + +public class UnionPointSet implements PointSet { + + private final Stream points; + + public UnionPointSet(List sets) { + points = sets.stream() + .map(PointSet::get) + .map(s -> s.collect(Collectors.toSet())) + .reduce(Sets::union).orElse(Collections.emptySet()) + .stream(); + } + + @Override + public Stream get() { + return points; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java new file mode 100644 index 0000000000..2f0a9f91b0 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/DoubleNavigableHolder.java @@ -0,0 +1,34 @@ +package com.dfsek.terra.addons.chunkgenerator.palette; + +import java.util.Map; +import java.util.NavigableMap; +import java.util.TreeMap; + + +public class DoubleNavigableHolder { + + private final NavigableMap map; + + public DoubleNavigableHolder(Map inputMap) { + NavigableMap map = new TreeMap<>(inputMap); + map.put(Double.MAX_VALUE, map.lastEntry().getValue()); + this.map = map; + } + + public T get(double threshold) { + return map.ceilingEntry(threshold).getValue(); + } + + enum Method { + CEILING, + FLOOR, + CLOSEST + } + + public class Single extends DoubleNavigableHolder { + + public Single(Map inputMap) { + super(inputMap); + } + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java new file mode 100644 index 0000000000..fb83db0ea3 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/SingletonPalette.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.addons.chunkgenerator.palette; + +import com.dfsek.terra.api.block.state.BlockState; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + + +public class SingletonPalette implements Palette { + private final BlockState blockState; + + public SingletonPalette(BlockState blockState) { + this.blockState = blockState; + } + + @Override + public BlockState get(int layer, double x, double y, double z, long seed) { + return blockState; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java new file mode 100644 index 0000000000..948a0fc32f --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/DoubleBiPredicate.java @@ -0,0 +1,6 @@ +package com.dfsek.terra.addons.chunkgenerator.util; + +@FunctionalInterface +public interface DoubleBiPredicate { + boolean test(double a, double b); +} diff --git a/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java new file mode 100644 index 0000000000..ebb1e6ad7a --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/java/com/dfsek/terra/addons/chunkgenerator/util/InstanceWrapper.java @@ -0,0 +1,12 @@ +package com.dfsek.terra.addons.chunkgenerator.util; + +import java.util.function.Supplier; + + +public record InstanceWrapper(T instance) implements Supplier { + + @Override + public T get() { + return instance; + } +} diff --git a/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml b/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml new file mode 100644 index 0000000000..1b7a2d3427 --- /dev/null +++ b/common/addons/chunk-generator-layered/src/main/resources/terra.addon.yml @@ -0,0 +1,12 @@ +schema-version: 1 +contributors: + - Terra contributors +id: chunk-generator-layered +version: @VERSION@ +entrypoints: + - "com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon" +website: + issues: https://github.com/PolyhedralDev/Terra/issues + source: https://github.com/PolyhedralDev/Terra + docs: https://terra.polydev.org +license: MIT License \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java index 89f6e038ce..f2f0c9386d 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/NoiseChunkGenerator3DAddon.java @@ -13,6 +13,7 @@ import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate; import com.dfsek.terra.addons.chunkgenerator.config.palette.slant.SlantLayerTemplate; import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo; import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; import com.dfsek.terra.addons.manifest.api.AddonInitializer; @@ -45,8 +46,8 @@ public void initialize() { .priority(1000) .then(event -> { - event.getPack().applyLoader(SlantHolder.CalculationMethod.class, - (type, o, loader, depthTracker) -> SlantHolder.CalculationMethod.valueOf((String) o)); + event.getPack().applyLoader(SlantCalculationMethod.class, + (type, o, loader, depthTracker) -> SlantCalculationMethod.valueOf((String) o)); NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate()); event.getPack().getContext().put(config); @@ -57,7 +58,8 @@ public void initialize() { pack -> new NoiseChunkGenerator3D(pack, platform, config.getElevationBlend(), config.getHorizontalRes(), config.getVerticalRes(), noisePropertiesPropertyKey, - paletteInfoPropertyKey)); + paletteInfoPropertyKey, config.getSlantCalculationMethod(), + config.isSlantPalettesEnabled())); event.getPack() .applyLoader(SlantHolder.Layer.class, SlantLayerTemplate::new); }) diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java index c3828bbbf2..ae1f1ca4a5 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/NoiseChunkGeneratorPackConfigTemplate.java @@ -4,7 +4,7 @@ import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; -import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.properties.Properties; @@ -24,7 +24,11 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Pr @Value("slant.calculation-method") @Default - private SlantHolder.@Meta CalculationMethod slantCalculationMethod = SlantHolder.CalculationMethod.Derivative; + private @Meta SlantCalculationMethod slantCalculationMethod = SlantCalculationMethod.Derivative; + + @Value("slant.disable-palettes") + @Default + private @Meta boolean disableSlantPalettes = false; public int getElevationBlend() { return elevationBlend; @@ -38,7 +42,11 @@ public int getVerticalRes() { return verticalRes; } - public SlantHolder.CalculationMethod getSlantCalculationMethod() { + public SlantCalculationMethod getSlantCalculationMethod() { return slantCalculationMethod; } + + public boolean isSlantPalettesEnabled() { + return !disableSlantPalettes; + } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java index 2d479f1a21..a4ff986e44 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/config/palette/BiomePaletteTemplate.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo; import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder; import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; @@ -27,7 +28,7 @@ public class BiomePaletteTemplate implements ObjectTemplate { private final Platform platform; - private final SlantHolder.CalculationMethod slantCalculationMethod; + private final SlantCalculationMethod slantCalculationMethod; @Value("slant") @Default @Description("The slant palettes to use in this biome.") @@ -56,7 +57,7 @@ public BlockState get(int layer, double x, double y, double z, long seed) { @Default private @Meta boolean updatePalette = false; - public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) { + public BiomePaletteTemplate(Platform platform, SlantCalculationMethod slantCalculationMethod) { this.platform = platform; this.slantCalculationMethod = slantCalculationMethod; } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java index 08dc93cbee..4f891d12ba 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/NoiseChunkGenerator3D.java @@ -11,11 +11,12 @@ import org.jetbrains.annotations.NotNull; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; -import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator; import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider; import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo; +import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; @@ -42,16 +43,23 @@ public class NoiseChunkGenerator3D implements ChunkGenerator { private final PropertyKey paletteInfoPropertyKey; private final PropertyKey noisePropertiesKey; + private final SlantCalculationMethod slantCalculationMethod; + + private final boolean useSlantPalettes; + public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBlend, int carverHorizontalResolution, int carverVerticalResolution, PropertyKey noisePropertiesKey, - PropertyKey paletteInfoPropertyKey) { + PropertyKey paletteInfoPropertyKey, + SlantCalculationMethod slantCalculationMethod, boolean useSlantPalettes) { this.platform = platform; this.air = platform.getWorldHandle().air(); this.carverHorizontalResolution = carverHorizontalResolution; this.carverVerticalResolution = carverVerticalResolution; this.paletteInfoPropertyKey = paletteInfoPropertyKey; this.noisePropertiesKey = noisePropertiesKey; + this.slantCalculationMethod = slantCalculationMethod; + this.useSlantPalettes = useSlantPalettes; int maxBlend = pack .getBiomeProvider() .stream() @@ -63,6 +71,17 @@ public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBl this.samplerCache = new SamplerProvider(platform, elevationBlend, noisePropertiesKey, maxBlend); } + private Palette paletteAt(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) { + SlantHolder slantHolder = paletteInfo.slantHolder(); + if(useSlantPalettes && slantHolder.isAboveDepth(depth)) { + double slant = slantCalculationMethod.slant(sampler, x, y, z); + if(slantHolder.isInSlantThreshold(slant)) { + return slantHolder.getPalette(slant).getPalette(y); + } + } + return paletteInfo.paletteHolder().getPalette(y); + } + @Override @SuppressWarnings("try") public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world, @@ -103,8 +122,7 @@ public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldPropertie if(sampler.sample(x, y, z) > 0) { if(carver.sample(x, y, z) <= 0) { - data = PaletteUtil - .getPalette(x, y, z, sampler, paletteInfo, paletteLevel) + data = paletteAt(x, y, z, sampler, paletteInfo, paletteLevel) .get(paletteLevel, cx, y, cz, seed); chunk.setBlock(x, y, z, data); paletteLevel++; @@ -135,7 +153,7 @@ public BlockState getBlock(WorldProperties world, int x, int y, int z, BiomeProv int fdX = Math.floorMod(x, 16); int fdZ = Math.floorMod(z, 16); - Palette palette = PaletteUtil.getPalette(fdX, y, fdZ, sampler, paletteInfo, 0); + Palette palette = paletteAt(fdX, y, fdZ, sampler, paletteInfo, 0); double noise = sampler.sample(fdX, y, fdZ); if(noise > 0) { int level = 0; @@ -157,11 +175,8 @@ public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvi public double getSlant(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) { int fdX = Math.floorMod(x, 16); int fdZ = Math.floorMod(z, 16); - return biomeProvider.getBiome(x, y, z, world.getSeed()) - .getContext() - .get(paletteInfoPropertyKey) - .slantHolder() - .calculateSlant(samplerCache.get(x, z, world, biomeProvider), fdX, y, fdZ); + Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider); + return slantCalculationMethod.slant(sampler, fdX, y, fdZ); } public SamplerProvider samplerProvider() { diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java deleted file mode 100644 index e7c20784cd..0000000000 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/PaletteUtil.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2020-2023 Polyhedral Development - * - * The Terra Core Addons are licensed under the terms of the MIT License. For more details, - * reference the LICENSE file in this module's root directory. - */ - -package com.dfsek.terra.addons.chunkgenerator.generation.math; - -import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; -import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo; -import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder; -import com.dfsek.terra.api.world.chunk.generation.util.Palette; - - -public final class PaletteUtil { - - public static Palette getPalette(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) { - SlantHolder slantHolder = paletteInfo.slantHolder(); - if(slantHolder.isAboveDepth(depth)) { - double slant = slantHolder.calculateSlant(sampler, x, y, z); - if(slantHolder.isInSlantThreshold(slant)) { - return slantHolder.getPalette(slant).getPalette(y); - } - } - - return paletteInfo.paletteHolder().getPalette(y); - } -} \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/SlantCalculationMethod.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/SlantCalculationMethod.java new file mode 100644 index 0000000000..1c03a038ad --- /dev/null +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/SlantCalculationMethod.java @@ -0,0 +1,69 @@ +package com.dfsek.terra.addons.chunkgenerator.generation.math; + +import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; +import com.dfsek.terra.api.util.vector.Vector3; + + +public enum SlantCalculationMethod { + DotProduct { + private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0); + + private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = { + Vector3.of(0, 0, -DERIVATIVE_DIST), + Vector3.of(0, 0, DERIVATIVE_DIST), + Vector3.of(0, -DERIVATIVE_DIST, 0), + Vector3.of(0, DERIVATIVE_DIST, 0), + Vector3.of(-DERIVATIVE_DIST, 0, 0), + Vector3.of(DERIVATIVE_DIST, 0, 0) + }; + + @Override + public double slant(Sampler3D sampler, double x, double y, double z) { + Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0); + for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) { + var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ()); + normalApproximation.add(point.mutable().multiply(scalar)); + } + return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize()); + } + + @Override + public boolean floorToThreshold() { + return false; + } + }, + + Derivative { + @Override + public double slant(Sampler3D sampler, double x, double y, double z) { + double baseSample = sampler.sample(x, y, z); + + double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST; + double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST; + double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST; + double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST; + double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; + double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; + + return Math.sqrt( + ((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1))); + } + + @Override + public boolean floorToThreshold() { + return true; + } + }; + + private static final double DERIVATIVE_DIST = 0.55; + + public abstract double slant(Sampler3D sampler, double x, double y, double z); + + /* + * Controls whether palettes should be applied before or after their respective thresholds. + * + * If true, slant values will map to the palette of the next floor threshold, otherwise they + * will map to the ceiling. + */ + public abstract boolean floorToThreshold(); +} diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java index 895c026980..08f1d16fea 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/MultipleSlantHolder.java @@ -14,6 +14,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder; @@ -21,7 +22,7 @@ public class MultipleSlantHolder extends SlantHolderImpl { private final NavigableMap layers; private final double slantThreshold; - MultipleSlantHolder(List slant, int slantDepth, CalculationMethod calculationMethod) { + MultipleSlantHolder(List slant, int slantDepth, SlantCalculationMethod calculationMethod) { super(slantDepth, calculationMethod); NavigableMap layers = new TreeMap<>( slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette))); diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java index 12f29ef18d..3f8ab5408a 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SingleSlantHolder.java @@ -1,5 +1,6 @@ package com.dfsek.terra.addons.chunkgenerator.palette.slant; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder; @@ -7,7 +8,7 @@ final class SingleSlantHolder extends SlantHolderImpl { private final SlantHolder.Layer layer; - public SingleSlantHolder(SlantHolder.Layer layer, int slantDepth, CalculationMethod calculationMethod) { + public SingleSlantHolder(SlantHolder.Layer layer, int slantDepth, SlantCalculationMethod calculationMethod) { super(slantDepth, calculationMethod); this.layer = layer; } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java index 359913d418..d4c2855cde 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolder.java @@ -2,19 +2,13 @@ import java.util.List; -import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder; -import com.dfsek.terra.api.util.vector.Vector3; public interface SlantHolder { SlantHolder EMPTY = new SlantHolder() { - @Override - public double calculateSlant(Sampler3D sampler, double x, double y, double z) { - throw new UnsupportedOperationException("Empty holder should not calculate slant"); - } - @Override public boolean isAboveDepth(int depth) { return false; @@ -31,7 +25,7 @@ public PaletteHolder getPalette(double slant) { } }; - static SlantHolder of(List layers, int slantDepth, CalculationMethod calculationMethod) { + static SlantHolder of(List layers, int slantDepth, SlantCalculationMethod calculationMethod) { if(layers.isEmpty()) { return EMPTY; } else if(layers.size() == 1) { @@ -40,8 +34,6 @@ static SlantHolder of(List layers, int slantDepth, Calculatio return new MultipleSlantHolder(layers, slantDepth, calculationMethod); } - double calculateSlant(Sampler3D sampler, double x, double y, double z); - boolean isAboveDepth(int depth); boolean isInSlantThreshold(double slant); @@ -49,71 +41,6 @@ static SlantHolder of(List layers, int slantDepth, Calculatio PaletteHolder getPalette(double slant); - enum CalculationMethod { - DotProduct { - private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0); - - private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = { - Vector3.of(0, 0, -DERIVATIVE_DIST), - Vector3.of(0, 0, DERIVATIVE_DIST), - Vector3.of(0, -DERIVATIVE_DIST, 0), - Vector3.of(0, DERIVATIVE_DIST, 0), - Vector3.of(-DERIVATIVE_DIST, 0, 0), - Vector3.of(DERIVATIVE_DIST, 0, 0) - }; - - @Override - public double slant(Sampler3D sampler, double x, double y, double z) { - Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0); - for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) { - var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ()); - normalApproximation.add(point.mutable().multiply(scalar)); - } - return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize()); - } - - @Override - public boolean floorToThreshold() { - return false; - } - }, - - Derivative { - @Override - public double slant(Sampler3D sampler, double x, double y, double z) { - double baseSample = sampler.sample(x, y, z); - - double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST; - double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST; - double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST; - double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST; - double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; - double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST; - - return Math.sqrt( - ((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1))); - } - - @Override - public boolean floorToThreshold() { - return true; - } - }; - - private static final double DERIVATIVE_DIST = 0.55; - - public abstract double slant(Sampler3D sampler, double x, double y, double z); - - /* - * Controls whether palettes should be applied before or after their respective thresholds. - * - * If true, slant values will map to the palette of the next floor threshold, otherwise they - * will map to the ceiling. - */ - public abstract boolean floorToThreshold(); - } - - record Layer(PaletteHolder palette, double threshold) { } } diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java index 13fc68ef13..bef21cdba9 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/palette/slant/SlantHolderImpl.java @@ -1,26 +1,19 @@ package com.dfsek.terra.addons.chunkgenerator.palette.slant; -import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D; +import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod; public abstract class SlantHolderImpl implements SlantHolder { protected final boolean floorToThreshold; - private final SlantHolder.CalculationMethod calculationMethod; private final int slantDepth; - protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) { + protected SlantHolderImpl(int slantDepth, SlantCalculationMethod calculationMethod) { this.floorToThreshold = calculationMethod.floorToThreshold(); - this.calculationMethod = calculationMethod; this.slantDepth = slantDepth; } protected abstract double getSlantThreshold(); - @Override - public final double calculateSlant(Sampler3D sampler, double x, double y, double z) { - return calculationMethod.slant(sampler, x, y, z); - } - @Override public final boolean isAboveDepth(int depth) { return depth <= slantDepth; diff --git a/common/addons/command-addons/src/main/java/com/dfsek/terra/addons/commands/addons/AddonsCommandAddon.java b/common/addons/command-addons/src/main/java/com/dfsek/terra/addons/commands/addons/AddonsCommandAddon.java index 58a22ef7a1..a1c0cfb748 100644 --- a/common/addons/command-addons/src/main/java/com/dfsek/terra/addons/commands/addons/AddonsCommandAddon.java +++ b/common/addons/command-addons/src/main/java/com/dfsek/terra/addons/commands/addons/AddonsCommandAddon.java @@ -1,7 +1,7 @@ package com.dfsek.terra.addons.commands.addons; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.CommandManager; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.description.Description; import com.dfsek.terra.addons.manifest.api.AddonInitializer; import com.dfsek.terra.api.Platform; @@ -30,7 +30,7 @@ public void initialize() { CommandManager manager = event.getCommandManager(); manager.command( - manager.commandBuilder("addons", ArgumentDescription.of("List installed Terra addons")) + manager.commandBuilder("addons", Description.of("List installed Terra addons")) .permission("terra.addons") .handler(context -> { StringBuilder addons = new StringBuilder("Installed addons:\n"); @@ -41,7 +41,7 @@ public void initialize() { .append('@') .append(addon.getVersion().getFormatted()) .append('\n')); - context.getSender().sendMessage(addons.toString()); + context.sender().sendMessage(addons.toString()); }) ) .command( @@ -61,7 +61,7 @@ public void initialize() { .append('@') .append(versions.getFormatted()) .append('\n')); - context.getSender().sendMessage(addonInfo.toString()); + context.sender().sendMessage(addonInfo.toString()); }) ); }); diff --git a/common/addons/command-packs/src/main/java/com/dfsek/terra/addons/commands/packs/PacksCommandAddon.java b/common/addons/command-packs/src/main/java/com/dfsek/terra/addons/commands/packs/PacksCommandAddon.java index 1d99af328a..6b840ef1f7 100644 --- a/common/addons/command-packs/src/main/java/com/dfsek/terra/addons/commands/packs/PacksCommandAddon.java +++ b/common/addons/command-packs/src/main/java/com/dfsek/terra/addons/commands/packs/PacksCommandAddon.java @@ -1,7 +1,7 @@ package com.dfsek.terra.addons.commands.packs; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.CommandManager; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.description.Description; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,7 +35,7 @@ public void initialize() { CommandManager manager = event.getCommandManager(); manager.command( - manager.commandBuilder("packs", ArgumentDescription.of("List installed config packs")) + manager.commandBuilder("packs", Description.of("List installed config packs")) .permission("terra.packs") .handler(context -> { StringBuilder packs = new StringBuilder("Installed packs:\n"); @@ -43,12 +43,12 @@ public void initialize() { .append(pack.getID()) .append('@') .append(pack.getVersion().getFormatted())); - context.getSender().sendMessage(packs.toString()); + context.sender().sendMessage(packs.toString()); }) ) .command( manager.commandBuilder("packs") - .literal("info", ArgumentDescription.of("Get information about a pack")) + .literal("info", Description.of("Get information about a pack")) .permission("terra.packs.info") .argument(RegistryArgument.of("pack", platform.getConfigRegistry())) .handler(context -> { @@ -65,21 +65,21 @@ public void initialize() { .append('@') .append(versions.getFormatted()) .append('\n')); - context.getSender().sendMessage(packInfo.toString()); + context.sender().sendMessage(packInfo.toString()); })) .command( manager.commandBuilder("packs") - .literal("reload", ArgumentDescription.of("Reload config packs")) + .literal("reload", Description.of("Reload config packs")) .permission("terra.packs.reload") .handler(context -> { - context.getSender().sendMessage("Reloading Terra..."); + context.sender().sendMessage("Reloading Terra..."); logger.info("Reloading Terra..."); if(platform.reload()) { logger.info("Terra reloaded successfully."); - context.getSender().sendMessage("Terra reloaded successfully."); + context.sender().sendMessage("Terra reloaded successfully."); } else { logger.error("Terra failed to reload."); - context.getSender().sendMessage( + context.sender().sendMessage( "Terra failed to reload. See logs for more information."); } })); diff --git a/common/addons/command-profiler/src/main/java/com/dfsek/terra/addons/commands/profiler/ProfilerCommandAddon.java b/common/addons/command-profiler/src/main/java/com/dfsek/terra/addons/commands/profiler/ProfilerCommandAddon.java index 2376c919bb..a1559c8c51 100644 --- a/common/addons/command-profiler/src/main/java/com/dfsek/terra/addons/commands/profiler/ProfilerCommandAddon.java +++ b/common/addons/command-profiler/src/main/java/com/dfsek/terra/addons/commands/profiler/ProfilerCommandAddon.java @@ -1,7 +1,7 @@ package com.dfsek.terra.addons.commands.profiler; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.CommandManager; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.description.Description; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,24 +33,24 @@ public void initialize() { CommandManager manager = event.getCommandManager(); manager .command( - manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler")) - .literal("start", ArgumentDescription.of("Start profiling"), "st") + manager.commandBuilder("profiler", Description.of("Access the profiler")) + .literal("start", Description.of("Start profiling"), "st") .permission("terra.profiler.start") .handler(context -> { platform.getProfiler().start(); - context.getSender().sendMessage("Profiling started."); + context.sender().sendMessage("Profiling started."); })) .command( - manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler")) - .literal("stop", ArgumentDescription.of("Stop profiling"), "s") + manager.commandBuilder("profiler", Description.of("Access the profiler")) + .literal("stop", Description.of("Stop profiling"), "s") .permission("terra.profiler.stop") .handler(context -> { platform.getProfiler().stop(); - context.getSender().sendMessage("Profiling stopped."); + context.sender().sendMessage("Profiling stopped."); })) .command( - manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler")) - .literal("query", ArgumentDescription.of("Query profiler results"), "q") + manager.commandBuilder("profiler", Description.of("Access the profiler")) + .literal("query", Description.of("Query profiler results"), "q") .permission("terra.profiler.query") .handler(context -> { StringBuilder data = new StringBuilder("Terra Profiler data: \n"); @@ -59,15 +59,15 @@ public void initialize() { .append(timings.toString()) .append('\n')); logger.info(data.toString()); - context.getSender().sendMessage("Profiling data dumped to console."); + context.sender().sendMessage("Profiling data dumped to console."); })) .command( - manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler")) - .literal("reset", ArgumentDescription.of("Reset the profiler"), "r") + manager.commandBuilder("profiler", Description.of("Access the profiler")) + .literal("reset", Description.of("Reset the profiler"), "r") .permission("terra.profiler.reset") .handler(context -> { platform.getProfiler().reset(); - context.getSender().sendMessage("Profiler reset."); + context.sender().sendMessage("Profiler reset."); })); }); } diff --git a/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java b/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java index 438546137c..e3e9f0c7bc 100644 --- a/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java +++ b/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java @@ -1,10 +1,11 @@ package com.dfsek.terra.addons.commands.structure; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.CommandManager; -import cloud.commandframework.arguments.standard.EnumArgument; -import cloud.commandframework.arguments.standard.LongArgument; -import cloud.commandframework.context.CommandContext; +import org.incendo.cloud.CommandManager; +import org.incendo.cloud.component.DefaultValue; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.description.Description; +import org.incendo.cloud.parser.standard.EnumParser; +import org.incendo.cloud.parser.standard.LongParser; import java.util.Random; @@ -31,7 +32,7 @@ public class StructureCommandAddon implements AddonInitializer { private BaseAddon addon; private static Registry getStructureRegistry(CommandContext sender) { - return sender.getSender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class); + return sender.sender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class); } @Override @@ -43,16 +44,16 @@ public void initialize() { CommandManager manager = event.getCommandManager(); manager.command( - manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures")) + manager.commandBuilder("structures", Description.of("Manage or generate structures")) .literal("generate") - .argument(RegistryArgument.builder("structure", + .optional(RegistryArgument.builder("structure", StructureCommandAddon::getStructureRegistry, TypeKey.of(Structure.class))) - .argument(LongArgument.optional("seed", 0)) - .argument(EnumArgument.optional(Rotation.class, "rotation", Rotation.NONE)) + .optional("seed", LongParser.longParser(), DefaultValue.constant(0L)) + .optional("rotation", EnumParser.enumParser(Rotation.class), DefaultValue.constant(Rotation.NONE)) .handler(context -> { Structure structure = context.get("structure"); - Entity sender = context.getSender().getEntity().orElseThrow(); + Entity sender = context.sender().getEntity().orElseThrow(); structure.generate( sender.position().toInt(), sender.world(), diff --git a/common/addons/config-biome/src/main/java/com/dfsek/terra/addons/biome/holder/PaletteHolderBuilder.java b/common/addons/config-biome/src/main/java/com/dfsek/terra/addons/biome/holder/PaletteHolderBuilder.java index e840f98178..a96cbcc484 100644 --- a/common/addons/config-biome/src/main/java/com/dfsek/terra/addons/biome/holder/PaletteHolderBuilder.java +++ b/common/addons/config-biome/src/main/java/com/dfsek/terra/addons/biome/holder/PaletteHolderBuilder.java @@ -7,11 +7,11 @@ package com.dfsek.terra.addons.biome.holder; +import com.dfsek.terra.api.world.chunk.generation.util.Palette; + import java.util.Map; import java.util.TreeMap; -import com.dfsek.terra.api.world.chunk.generation.util.Palette; - public class PaletteHolderBuilder { private final TreeMap paletteMap = new TreeMap<>(); diff --git a/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PointSetDistributor.java b/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PointSetDistributor.java index f85d41e5f7..4285af4869 100644 --- a/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PointSetDistributor.java +++ b/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PointSetDistributor.java @@ -7,11 +7,11 @@ package com.dfsek.terra.addons.feature.distributor.distributors; -import java.util.Set; - import com.dfsek.terra.addons.feature.distributor.util.Point; import com.dfsek.terra.api.structure.feature.Distributor; +import java.util.Set; + public class PointSetDistributor implements Distributor { private final Set points; diff --git a/common/addons/config-noise-function/build.gradle.kts b/common/addons/config-noise-function/build.gradle.kts index af2284b48f..83d927a017 100644 --- a/common/addons/config-noise-function/build.gradle.kts +++ b/common/addons/config-noise-function/build.gradle.kts @@ -1,4 +1,4 @@ -version = version("1.1.0") +version = version("1.2.0") dependencies { compileOnlyApi(project(":common:addons:manifest-addon-loader")) diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseAddon.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseAddon.java index ca3aa1a448..3fd52950c0 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseAddon.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseAddon.java @@ -17,6 +17,7 @@ import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate; import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler; import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate; +import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate; import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate; import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate; import com.dfsek.terra.addons.noise.config.templates.ImageSamplerTemplate; @@ -28,6 +29,7 @@ import com.dfsek.terra.addons.noise.config.templates.noise.DistanceSamplerTemplate; import com.dfsek.terra.addons.noise.config.templates.noise.ExpressionFunctionTemplate; import com.dfsek.terra.addons.noise.config.templates.noise.GaborNoiseTemplate; +import com.dfsek.terra.addons.noise.config.templates.noise.PseudoErosionTemplate; import com.dfsek.terra.addons.noise.config.templates.noise.SimpleNoiseTemplate; import com.dfsek.terra.addons.noise.config.templates.noise.fractal.BrownianMotionTemplate; import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate; @@ -63,6 +65,7 @@ import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.functional.FunctionalEventHandler; import com.dfsek.terra.api.inject.annotations.Inject; +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.util.reflection.TypeKey; @@ -94,7 +97,8 @@ public void initialize() { (type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o)) .applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new) .applyLoader(FunctionTemplate.class, FunctionTemplate::new) - .applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new); + .applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new) + .applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new); noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new); noiseRegistry.register(addon.key("NORMAL"), NormalNormalizerTemplate::new); @@ -117,7 +121,7 @@ public void initialize() { noiseRegistry.register(addon.key("PERLIN"), () -> new SimpleNoiseTemplate(PerlinSampler::new)); noiseRegistry.register(addon.key("SIMPLEX"), () -> new SimpleNoiseTemplate(SimplexSampler::new)); noiseRegistry.register(addon.key("GABOR"), GaborNoiseTemplate::new); - + noiseRegistry.register(addon.key("PSEUDOEROSION"), PseudoErosionTemplate::new); noiseRegistry.register(addon.key("VALUE"), () -> new SimpleNoiseTemplate(ValueSampler::new)); noiseRegistry.register(addon.key("VALUE_CUBIC"), () -> new SimpleNoiseTemplate(ValueCubicSampler::new)); diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseConfigPackTemplate.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseConfigPackTemplate.java index c41af17633..d6ac6c00c5 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseConfigPackTemplate.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/NoiseConfigPackTemplate.java @@ -11,14 +11,14 @@ import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; -import java.util.LinkedHashMap; -import java.util.Map; - import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler; import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate; import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.properties.Properties; +import java.util.LinkedHashMap; +import java.util.Map; + @SuppressWarnings("FieldMayBeFinal") public class NoiseConfigPackTemplate implements ConfigTemplate, Properties { diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/DerivativeNoiseSamplerTemplate.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/DerivativeNoiseSamplerTemplate.java new file mode 100644 index 0000000000..9e66b23ead --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/DerivativeNoiseSamplerTemplate.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.addons.noise.config.templates; + +import com.dfsek.tectonic.api.config.template.annotations.Value; +import com.dfsek.tectonic.api.exception.ValidationException; + +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class DerivativeNoiseSamplerTemplate extends SamplerTemplate { + + @Value(".") + private NoiseSampler sampler; + + @Override + public boolean validate() throws ValidationException { + if(!DerivativeNoiseSampler.isDifferentiable(sampler)) throw new ValidationException( + "Provided sampler does not support calculating a derivative"); + return super.validate(); + } + + @Override + public DerivativeNoiseSampler get() { + return (DerivativeNoiseSampler) sampler; + } +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/DerivativeNoiseTemplate.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/DerivativeNoiseTemplate.java new file mode 100644 index 0000000000..c9100e3444 --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/DerivativeNoiseTemplate.java @@ -0,0 +1,8 @@ +package com.dfsek.terra.addons.noise.config.templates.noise; + +import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction; + + +public abstract class DerivativeNoiseTemplate extends NoiseTemplate { + +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/PseudoErosionTemplate.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/PseudoErosionTemplate.java new file mode 100644 index 0000000000..cda91ec326 --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/config/templates/noise/PseudoErosionTemplate.java @@ -0,0 +1,79 @@ +package com.dfsek.terra.addons.noise.config.templates.noise; + +import com.dfsek.tectonic.api.config.template.annotations.Default; +import com.dfsek.tectonic.api.config.template.annotations.Value; + +import com.dfsek.terra.addons.noise.samplers.noise.PseudoErosionSampler; +import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler; +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; + + +public class PseudoErosionTemplate extends NoiseTemplate { + @Value("frequency") + @Default + protected @Meta double frequency = 1d; + + @Value("octaves") + @Default + private int octaves = 4; + + @Value("lacunarity") + @Default + private double lacunarity = 2.0; + + @Value("gain") + @Default + private double gain = 0.5; + + @Value("slope-strength") + @Default + private double slopeStrength = 1.0; + + + @Value("branch-strength") + @Default + private double branchStrength = 1.0; + + @Value("strength") + @Default + private double strength = 0.04; + + @Value("erosion-frequency") + @Default + private double erosionFrequency = 0.02; + + @Value("sampler") + @Default + private DerivativeNoiseSampler heightSampler = new OpenSimplex2Sampler(); + + @Value("slope-mask.enable") + @Default + private boolean slopeMask = true; + + @Value("slope-mask.none") + @Default + private double slopeMaskNone = -0.5; + + @Value("slope-mask.full") + @Default + private double slopeMaskFull = 1; + + @Value("jitter") + @Default + private double jitterModifier = 1; + + @Value("average-impulses") + @Default + private boolean averageErosionImpulses = true; + + @Override + public PseudoErosionSampler get() { + PseudoErosionSampler pseudoErosion = new PseudoErosionSampler(octaves, gain, lacunarity, + slopeStrength, branchStrength, strength, + erosionFrequency, heightSampler, slopeMask, slopeMaskFull, slopeMaskNone, jitterModifier, averageErosionImpulses); + pseudoErosion.setFrequency(frequency); + pseudoErosion.setSalt(salt); + return pseudoErosion; + } +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/FunctionUtil.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/FunctionUtil.java index 5dbc740ecf..d47693cde8 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/FunctionUtil.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/FunctionUtil.java @@ -11,6 +11,8 @@ import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction; import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2; import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3; +import com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction2; +import com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction3; public class FunctionUtil { @@ -23,10 +25,15 @@ public static Map convertFunctionsAndSamplers(Map entry : functions.entrySet()) { functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue())); } - samplers.forEach((id, sampler) -> functionMap.put(id, - sampler.getDimensions() == 2 ? - new NoiseFunction2(sampler.getSampler()) : - new NoiseFunction3(sampler.getSampler()))); + samplers.forEach((id, sampler) -> { + if(sampler.getDimensions() == 2) { + functionMap.put(id, new NoiseFunction2(sampler.getSampler())); + functionMap.put(id + "Salted", new SaltedNoiseFunction2(sampler.getSampler())); + } else { + functionMap.put(id, new NoiseFunction3(sampler.getSampler())); + functionMap.put(id + "Salted", new SaltedNoiseFunction3(sampler.getSampler())); + } + }); return functionMap; } } diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction2.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction2.java new file mode 100644 index 0000000000..41ddd12479 --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction2.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.addons.noise.paralithic.noise; + +import com.dfsek.paralithic.functions.dynamic.Context; +import com.dfsek.paralithic.functions.dynamic.DynamicFunction; +import com.dfsek.paralithic.node.Statefulness; +import org.jetbrains.annotations.NotNull; + +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class SaltedNoiseFunction2 implements DynamicFunction { + private final NoiseSampler gen; + + public SaltedNoiseFunction2(NoiseSampler gen) { + this.gen = gen; + } + + @Override + public double eval(double... args) { + throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context."); + } + + @Override + public double eval(Context context, double... args) { + return gen.noise(((SeedContext) context).getSeed() + (long) args[2], args[0], args[1]); + } + + @Override + public int getArgNumber() { + return 3; + } + + @Override + public @NotNull Statefulness statefulness() { + return Statefulness.CONTEXTUAL; + } +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction3.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction3.java new file mode 100644 index 0000000000..d4549127cc --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/paralithic/noise/SaltedNoiseFunction3.java @@ -0,0 +1,37 @@ +package com.dfsek.terra.addons.noise.paralithic.noise; + +import com.dfsek.paralithic.functions.dynamic.Context; +import com.dfsek.paralithic.functions.dynamic.DynamicFunction; +import com.dfsek.paralithic.node.Statefulness; +import org.jetbrains.annotations.NotNull; + +import com.dfsek.terra.api.noise.NoiseSampler; + + +public class SaltedNoiseFunction3 implements DynamicFunction { + private final NoiseSampler gen; + + public SaltedNoiseFunction3(NoiseSampler gen) { + this.gen = gen; + } + + @Override + public double eval(double... args) { + throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context."); + } + + @Override + public double eval(Context context, double... args) { + return gen.noise(((SeedContext) context).getSeed() + (long) args[3], args[0], args[1], args[2]); + } + + @Override + public int getArgNumber() { + return 4; + } + + @Override + public @NotNull Statefulness statefulness() { + return Statefulness.CONTEXTUAL; + } +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/DerivativeNoiseFunction.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/DerivativeNoiseFunction.java new file mode 100644 index 0000000000..0d654eb646 --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/DerivativeNoiseFunction.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.addons.noise.samplers.noise; + +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; + + +public abstract class DerivativeNoiseFunction extends NoiseFunction implements DerivativeNoiseSampler { + @Override + public boolean isDifferentiable() { + return true; + } + + @Override + public double[] noised(long seed, double x, double y) { + return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency); + } + + @Override + public double[] noised(long seed, double x, double y, double z) { + return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency, z * frequency); + } + + public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y); + + public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y, double z); +} diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/PseudoErosionSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/PseudoErosionSampler.java new file mode 100644 index 0000000000..ecb566ca7b --- /dev/null +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/PseudoErosionSampler.java @@ -0,0 +1,173 @@ +package com.dfsek.terra.addons.noise.samplers.noise; + + +import com.dfsek.terra.api.noise.DerivativeNoiseSampler; +import com.dfsek.terra.api.util.MathUtil; + + +public class PseudoErosionSampler extends NoiseFunction { + public static final double TAU = 2.0 * Math.PI; + private static final double HASH_X = 0.3183099f; + private static final double HASH_Y = 0.3678794f; + public final double gain; + public final double lacunarity; + public final double slopeStrength; + public final double branchStrength; + public final double erosionStrength; + private final int octaves; + private final double erosionFrequency; + private final DerivativeNoiseSampler sampler; + private final boolean slopeMask; + private final double slopeMaskFullSq; + private final double slopeMaskNoneSq; + private final double jitter; + private final double maxCellDistSq; + private final double maxCellDistSqRecip; + private final boolean averageErosionImpulses; + + public PseudoErosionSampler(int octaves, double gain, double lacunarity, double slopeStrength, double branchStrength, + double erosionStrength, double erosionFrequency, DerivativeNoiseSampler sampler, + boolean slopeMask, double slopeMaskFull, double slopeMaskNone, double jitterModifier, + boolean averageErosionImpulses) { + this.octaves = octaves; + this.gain = gain; + this.lacunarity = lacunarity; + this.slopeStrength = slopeStrength; + this.branchStrength = branchStrength; + this.erosionStrength = erosionStrength; + this.erosionFrequency = erosionFrequency; + this.sampler = sampler; + this.slopeMask = slopeMask; + // Square these values and maintain sign since they're compared to a + // squared value, otherwise a sqrt would need to be used + this.slopeMaskFullSq = slopeMaskFull * slopeMaskFull * Math.signum(slopeMaskFull); + this.slopeMaskNoneSq = slopeMaskNone * slopeMaskNone * Math.signum((slopeMaskNone)); + this.jitter = 0.43701595 * jitterModifier; + this.averageErosionImpulses = averageErosionImpulses; + this.maxCellDistSq = 1 + jitter * jitter; + this.maxCellDistSqRecip = 1 / maxCellDistSq; + } + + public static double hashX(double seed, double n) { + // Swapped the components here + double nx = HASH_X * n * seed; + return -1.0f + 2.0f * fract(nx); + } + + public static double hashY(double seed, double n) { + double ny = HASH_Y * n * seed; + return -1.0f + 2.0f * fract(ny); + } + + public static double fract(double x) { + return (x - Math.floor(x)); + } + + public static double smoothstep(double edge0, double edge1, double x) { + // Scale, bias and saturate x to 0..1 range + x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f); + // Evaluate polynomial + return x * x * (3 - 2 * x); + } + + public static double clamp(double x, double minVal, double maxVal) { + return Math.max(minVal, Math.min(maxVal, x)); + } + + public static double dot(double x1, double y1, double x2, double y2) { + return x1 * x2 + y1 * y2; + } + + public double[] erosion(int seed, double x, double y, double dirX, double dirY) { + int gridX = (int) Math.round(x); + int gridY = (int) Math.round(y); + double noise = 0.0f; + double dirOutX = 0.0f; + double dirOutY = 0.0f; + double cumAmp = 0.0f; + + for(int cellX = gridX - 1; cellX <= gridX + 1; cellX++) { + for(int cellY = gridY - 1; cellY <= gridY + 1; cellY++) { + double cellHash = hash(seed, cellX, cellY); + double cellOffsetX = hashX(seed, cellHash) * jitter; + double cellOffsetY = hashY(seed, cellHash) * jitter; + double cellOriginDeltaX = (x - cellX) + cellOffsetX; + double cellOriginDeltaY = (y - cellY) + cellOffsetY; + double cellOriginDistSq = cellOriginDeltaX * cellOriginDeltaX + cellOriginDeltaY * cellOriginDeltaY; + if(cellOriginDistSq > maxCellDistSq) continue; // Skip calculating cells too far away + double ampTmp = (cellOriginDistSq * maxCellDistSqRecip) - 1; + double amp = ampTmp * ampTmp; // Decrease cell amplitude further away + cumAmp += amp; + double directionalStrength = dot(cellOriginDeltaX, cellOriginDeltaY, dirX, dirY) * TAU; + noise += MathUtil.cos(directionalStrength) * amp; + double sinAngle = MathUtil.sin(directionalStrength) * amp; + dirOutX -= sinAngle * (cellOriginDeltaX + dirX); + dirOutY -= sinAngle * (cellOriginDeltaY + dirY); + } + } + if(averageErosionImpulses && cumAmp != 0) { + noise /= cumAmp; + dirOutX /= cumAmp; + dirOutY /= cumAmp; + } + return new double[]{ noise, dirOutX, dirOutY }; + } + + public double heightMap(long seed, double x, double y) { + double[] sample = sampler.noised(seed, x, y); + double height = sample[0]; + double heightDirX = sample[1]; + double heightDirY = sample[2]; + + // Take the curl of the normal to get the gradient facing down the slope + double baseDirX = heightDirY * slopeStrength; + double baseDirY = -heightDirX * slopeStrength; + + double erosion = 0.0f; + double dirX = 0.0f; + double dirY = 0.0f; + double amp = 1.0f; + double cumAmp = 0.0f; + double freq = 1.0f; + + // Stack erosion octaves + for(int i = 0; i < octaves; i++) { + double[] erosionResult = erosion((int) seed, + x * freq * erosionFrequency, + y * freq * erosionFrequency, + baseDirX + dirY * branchStrength, + baseDirY - dirX * branchStrength); + erosion += erosionResult[0] * amp; + dirX += erosionResult[1] * amp * freq; + dirY += erosionResult[2] * amp * freq; + cumAmp += amp; + amp *= gain; + freq *= lacunarity; + } + + // Normalize erosion noise + erosion /= cumAmp; + // [-1, 1] -> [0, 1] + erosion = erosion * 0.5F + 0.5F; + + // Without masking, erosion noise in areas with small gradients tend to produce mounds, + // this reduces erosion amplitude towards smaller gradients to avoid this + if(slopeMask) { + double dirMagSq = dot(baseDirX, baseDirY, baseDirX, baseDirY); + double flatness = smoothstep((double) slopeMaskNoneSq, slopeMaskFullSq, dirMagSq); + erosion *= flatness; + } + + return height + erosion * erosionStrength; + } + + @Override + public double getNoiseRaw(long seed, double x, double y) { + return heightMap(seed, x, y); + } + + @Override + public double getNoiseRaw(long seed, double x, double y, double z) { + return getNoiseRaw(seed, x, z); + } +} \ No newline at end of file diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java index 64f4ede055..bc766c7316 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/BrownianMotionSampler.java @@ -24,7 +24,7 @@ public double getNoiseRaw(long seed, double x, double y) { for(int i = 0; i < octaves; i++) { double noise = input.noise(seed++, x, y); sum += noise * amp; - amp *= MathUtil.lerp(1.0, Math.min(noise + 1, 2) * 0.5, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise + 1, 2) * 0.5); x *= lacunarity; y *= lacunarity; @@ -42,7 +42,7 @@ public double getNoiseRaw(long seed, double x, double y, double z) { for(int i = 0; i < octaves; i++) { double noise = input.noise(seed++, x, y, z); sum += noise * amp; - amp *= MathUtil.lerp(1.0, (noise + 1) * 0.5, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, (noise + 1) * 0.5); x *= lacunarity; y *= lacunarity; diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/PingPongSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/PingPongSampler.java index 653484fa11..761a5deaa3 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/PingPongSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/PingPongSampler.java @@ -36,7 +36,7 @@ public double getNoiseRaw(long seed, double x, double y) { for(int i = 0; i < octaves; i++) { double noise = pingPong((input.noise(seed++, x, y) + 1) * pingPongStrength); sum += (noise - 0.5) * 2 * amp; - amp *= MathUtil.lerp(1.0, noise, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, noise); x *= lacunarity; y *= lacunarity; @@ -54,7 +54,7 @@ public double getNoiseRaw(long seed, double x, double y, double z) { for(int i = 0; i < octaves; i++) { double noise = pingPong((input.noise(seed++, x, y, z) + 1) * pingPongStrength); sum += (noise - 0.5) * 2 * amp; - amp *= MathUtil.lerp(1.0, noise, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, noise); x *= lacunarity; y *= lacunarity; diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/RidgedFractalSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/RidgedFractalSampler.java index 9ebb20ba08..1b45ed8206 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/RidgedFractalSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/fractal/RidgedFractalSampler.java @@ -25,7 +25,7 @@ public double getNoiseRaw(long seed, double x, double y) { for(int i = 0; i < octaves; i++) { double noise = Math.abs(input.noise(seed++, x, y)); sum += (noise * -2 + 1) * amp; - amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise); x *= lacunarity; y *= lacunarity; @@ -43,7 +43,7 @@ public double getNoiseRaw(long seed, double x, double y, double z) { for(int i = 0; i < octaves; i++) { double noise = Math.abs(input.noise(seed++, x, y, z)); sum += (noise * -2 + 1) * amp; - amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength); + amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise); x *= lacunarity; y *= lacunarity; diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2SSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2SSampler.java index e3488a6769..86adcee3bb 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2SSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2SSampler.java @@ -276,4 +276,424 @@ public double getNoiseRaw(long sl, double x, double y, double z) { return value * 9.046026385208288; } + + @Override + public boolean isDifferentiable() { + return true; + } + + @Override + public double[] getNoiseDerivativeRaw(long sl, double x, double y) { + int seed = (int) sl; + // 2D OpenSimplex2S case is a modified 2D simplex noise. + + final double SQRT3 = 1.7320508075688772935274463415059; + final double G2 = (3 - SQRT3) / 6; + + final double F2 = 0.5f * (SQRT3 - 1); + double s = (x + y) * F2; + x += s; + y += s; + + + int i = (int) Math.floor(x); + int j = (int) Math.floor(y); + double xi = x - i; + double yi = y - j; + + i *= PRIME_X; + j *= PRIME_Y; + int i1 = i + PRIME_X; + int j1 = j + PRIME_Y; + + double t = (xi + yi) * G2; + double x0 = xi - t; + double y0 = yi - t; + + double[] out = { 0.0f, 0.0f, 0.0f }; + + double a0 = (2.0 / 3.0) - x0 * x0 - y0 * y0; + double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0; + int gi0 = gradCoordIndex(seed, i, j); + double gx0 = GRADIENTS_2_D[gi0], gy0 = GRADIENTS_2_D[gi0 | 1]; + double rampValue0 = gx0 * x0 + gy0 * y0; + out[0] = aaaa0 * rampValue0; + out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0; + out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0; + + + double a1 = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0); + double x1 = x0 - (1 - 2 * G2); + double y1 = y0 - (1 - 2 * G2); + double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1; + int gi1 = gradCoordIndex(seed, i1, j1); + double gx1 = GRADIENTS_2_D[gi1], gy1 = GRADIENTS_2_D[gi1 | 1]; + double rampValue1 = gx1 * x1 + gy1 * y1; + out[0] += aaaa1 * rampValue1; + out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1; + out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1; + + // Nested conditionals were faster than compact bit logic/arithmetic. + double xmyi = xi - yi; + if(t > G2) { + if(xi + xmyi > 1) { + double x2 = x0 + (3 * G2 - 2); + double y2 = y0 + (3 * G2 - 1); + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i + (PRIME_X << 1), j + PRIME_Y); + double gx2 = GRADIENTS_2_D[gi2 | 0], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } else { + double x2 = x0 + G2; + double y2 = y0 + (G2 - 1); + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i, j + PRIME_Y); + double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } + + if(yi - xmyi > 1) { + double x3 = x0 + (3 * G2 - 1); + double y3 = y0 + (3 * G2 - 2); + double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3; + if(a3 > 0) { + double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3; + int gi3 = gradCoordIndex(seed, i + PRIME_X, j + (PRIME_Y << 1)); + double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1]; + double rampValue3 = gx3 * x3 + gy3 * y3; + out[0] += aaaa3 * rampValue3; + out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3; + out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3; + } + } else { + double x3 = x0 + (G2 - 1); + double y3 = y0 + G2; + double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3; + if(a3 > 0) { + double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3; + int gi3 = gradCoordIndex(seed, i + PRIME_X, j); + double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1]; + double rampValue3 = gx3 * x3 + gy3 * y3; + out[0] += aaaa3 * rampValue3; + out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3; + out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3; + } + } + } else { + if(xi + xmyi < 0) { + double x2 = x0 + (1 - G2); + double y2 = y0 - G2; + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i - PRIME_X, j); + double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } else { + double x2 = x0 + (G2 - 1); + double y2 = y0 + G2; + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i + PRIME_X, j); + double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } + + if(yi < xmyi) { + double x2 = x0 - G2; + double y2 = y0 - (G2 - 1); + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i, j - PRIME_Y); + double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } else { + double x2 = x0 + G2; + double y2 = y0 + (G2 - 1); + double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2; + if(a2 > 0) { + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i, j + PRIME_Y); + double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1]; + double rampValue2 = gx2 * x2 + gy2 * y2; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2; + } + } + } + out[0] *= 18.24196194486065; + out[1] *= 18.24196194486065; + out[2] *= 18.24196194486065; + return out; + } + + @Override + public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) { + int seed = (int) sl; + // 3D OpenSimplex2S case uses two offset rotated cube grids. + final double R3 = (2.0 / 3.0); + double r = (x + y + z) * R3; // Rotation, not skew + x = r - x; + y = r - y; + z = r - z; + + + int i = (int) Math.floor(x); + int j = (int) Math.floor(y); + int k = (int) Math.floor(z); + double xi = x - i; + double yi = y - j; + double zi = z - k; + + i *= PRIME_X; + j *= PRIME_Y; + k *= PRIME_Z; + int seed2 = seed + 1293373; + + int xNMask = (int) (-0.5 - xi); + int yNMask = (int) (-0.5 - yi); + int zNMask = (int) (-0.5 - zi); + + double[] out = { 0.0f, 0.0f, 0.0f, 0.0f }; + + double x0 = xi + xNMask; + double y0 = yi + yNMask; + double z0 = zi + zNMask; + double a0 = 0.75 - x0 * x0 - y0 * y0 - z0 * z0; + double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0; + int gi0 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z)); + double gx0 = GRADIENTS_3D[gi0], gy0 = GRADIENTS_3D[gi0 | 1], gz0 = GRADIENTS_3D[gi0 | 2]; + double rampValue0 = gx0 * x0 + gy0 * y0 + gz0 * z0; + out[0] = aaaa0 * rampValue0; + out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0; + out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0; + out[3] = gz0 * aaaa0 - 8 * rampValue0 * aaa0 * z0; + + double x1 = xi - 0.5; + double y1 = yi - 0.5; + double z1 = zi - 0.5; + double a1 = 0.75 - x1 * x1 - y1 * y1 - z1 * z1; + double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1; + int gi1 = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + PRIME_Z); + double gx1 = GRADIENTS_3D[gi1], gy1 = GRADIENTS_3D[gi1 | 1], gz1 = GRADIENTS_3D[gi1 | 2]; + double rampValue1 = gx1 * x1 + gy1 * y1 + gz1 * z1; + out[0] += aaaa1 * rampValue1; + out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1; + out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1; + out[3] += gz1 * aaaa1 - 8 * rampValue1 * aaa1 * z1; + + double xAFlipMask0 = ((xNMask | 1) << 1) * x1; + double yAFlipMask0 = ((yNMask | 1) << 1) * y1; + double zAFlipMask0 = ((zNMask | 1) << 1) * z1; + double xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0; + double yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0; + double zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0; + + boolean skip5 = false; + double a2 = xAFlipMask0 + a0; + if(a2 > 0) { + double x2 = x0 - (xNMask | 1); + double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2; + int gi2 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z)); + double gx2 = GRADIENTS_3D[gi2], gy2 = GRADIENTS_3D[gi2 | 1], gz2 = GRADIENTS_3D[gi2 | 2]; + double rampValue2 = gx2 * x2 + gy2 * y0 + gz2 * z0; + out[0] += aaaa2 * rampValue2; + out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2; + out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y0; + out[3] += gz2 * aaaa2 - 8 * rampValue2 * aaa2 * z0; + } else { + double a3 = yAFlipMask0 + zAFlipMask0 + a0; + if(a3 > 0) { + double y3 = y0 - (yNMask | 1); + double z3 = z0 - (zNMask | 1); + double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3; + int gi3 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (~zNMask & PRIME_Z)); + double gx3 = GRADIENTS_3D[gi3], gy3 = GRADIENTS_3D[gi3 | 1], gz3 = GRADIENTS_3D[gi3 | 2]; + double rampValue3 = gx3 * x0 + gy3 * y3 + gz3 * z3; + out[0] += aaaa3 * rampValue3; + out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x0; + out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3; + out[3] += gz3 * aaaa3 - 8 * rampValue3 * aaa3 * z3; + } + + double a4 = xAFlipMask1 + a1; + if(a4 > 0) { + double x4 = (xNMask | 1) + x1; + double aa4 = a4 * a4, aaa4 = aa4 * a4, aaaa4 = aa4 * aa4; + int gi4 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + PRIME_Z); + double gx4 = GRADIENTS_3D[gi4], gy4 = GRADIENTS_3D[gi4 | 1], gz4 = GRADIENTS_3D[gi4 | 2]; + double rampValue4 = gx4 * x4 + gy4 * y1 + gz4 * z1; + out[0] += aaaa4 * rampValue4; + out[1] += gx4 * aaaa4 - 8 * rampValue4 * aaa4 * x4; + out[2] += gy4 * aaaa4 - 8 * rampValue4 * aaa4 * y1; + out[3] += gz4 * aaaa4 - 8 * rampValue4 * aaa4 * z1; + skip5 = true; + } + } + + boolean skip9 = false; + double a6 = yAFlipMask0 + a0; + if(a6 > 0) { + double y6 = y0 - (yNMask | 1); + double aa6 = a6 * a6, aaa6 = aa6 * a6, aaaa6 = aa6 * aa6; + int gi6 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z)); + double gx6 = GRADIENTS_3D[gi6], gy6 = GRADIENTS_3D[gi6 | 1], gz6 = GRADIENTS_3D[gi6 | 2]; + double rampValue6 = gx6 * x0 + gy6 * y6 + gz6 * z0; + out[0] += aaaa6 * rampValue6; + out[1] += gx6 * aaaa6 - 8 * rampValue6 * aaa6 * x0; + out[2] += gy6 * aaaa6 - 8 * rampValue6 * aaa6 * y6; + out[3] += gz6 * aaaa6 - 8 * rampValue6 * aaa6 * z0; + } else { + double a7 = xAFlipMask0 + zAFlipMask0 + a0; + if(a7 > 0) { + double x7 = x0 - (xNMask | 1); + double z7 = z0 - (zNMask | 1); + double aa7 = a7 * a7, aaa7 = aa7 * a7, aaaa7 = aa7 * aa7; + int gi7 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z)); + double gx7 = GRADIENTS_3D[gi7], gy7 = GRADIENTS_3D[gi7 | 1], gz7 = GRADIENTS_3D[gi7 | 2]; + double rampValue7 = gx7 * x7 + gy7 * y0 + gz7 * z7; + out[0] += aaaa7 * rampValue7; + out[1] += gx7 * aaaa7 - 8 * rampValue7 * aaa7 * x7; + out[2] += gy7 * aaaa7 - 8 * rampValue7 * aaa7 * y0; + out[3] += gz7 * aaaa7 - 8 * rampValue7 * aaa7 * z7; + } + + double a8 = yAFlipMask1 + a1; + if(a8 > 0) { + double y8 = (yNMask | 1) + y1; + double aa8 = a8 * a8, aaa8 = aa8 * a8, aaaa8 = aa8 * aa8; + int gi8 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z); + double gx8 = GRADIENTS_3D[gi8], gy8 = GRADIENTS_3D[gi8 | 1], gz8 = GRADIENTS_3D[gi8 | 2]; + double rampValue8 = gx8 * x1 + gy8 * y8 + gz8 * z1; + out[0] += aaaa8 * rampValue8; + out[1] += gx8 * aaaa8 - 8 * rampValue8 * aaa8 * x1; + out[2] += gy8 * aaaa8 - 8 * rampValue8 * aaa8 * y8; + out[3] += gz8 * aaaa8 - 8 * rampValue8 * aaa8 * z1; + skip9 = true; + } + } + + boolean skipD = false; + double aA = zAFlipMask0 + a0; + if(aA > 0) { + double zA = z0 - (zNMask | 1); + double aaA = aA * aA, aaaA = aaA * aA, aaaaA = aaA * aaA; + int giA = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z)); + double gxA = GRADIENTS_3D[giA], gyA = GRADIENTS_3D[giA | 1], gzA = GRADIENTS_3D[giA | 2]; + double rampValueA = gxA * x0 + gyA * y0 + gzA * zA; + out[0] += aaaaA * rampValueA; + out[1] += gxA * aaaaA - 8 * rampValueA * aaaA * x0; + out[2] += gyA * aaaaA - 8 * rampValueA * aaaA * y0; + out[3] += gzA * aaaaA - 8 * rampValueA * aaaA * zA; + } else { + double aB = xAFlipMask0 + yAFlipMask0 + a0; + if(aB > 0) { + double xB = x0 - (xNMask | 1); + double yB = y0 - (yNMask | 1); + double aaB = aB * aB, aaaB = aaB * aB, aaaaB = aaB * aaB; + int giB = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z)); + double gxB = GRADIENTS_3D[giB], gyB = GRADIENTS_3D[giB | 1], gzB = GRADIENTS_3D[giB | 2]; + double rampValueB = gxB * xB + gyB * yB + gzB * z0; + out[0] += aaaaB * rampValueB; + out[1] += gxB * aaaaB - 8 * rampValueB * aaaB * xB; + out[2] += gyB * aaaaB - 8 * rampValueB * aaaB * yB; + out[3] += gzB * aaaaB - 8 * rampValueB * aaaB * z0; + } + + double aC = zAFlipMask1 + a1; + if(aC > 0) { + double zC = (zNMask | 1) + z1; + double aaC = aC * aC, aaaC = aaC * aC, aaaaC = aaC * aaC; + int giC = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + (zNMask & (PRIME_Z << 1))); + double gxC = GRADIENTS_3D[giC], gyC = GRADIENTS_3D[giC | 1], gzC = GRADIENTS_3D[giC | 2]; + double rampValueC = gxC * x1 + gyC * y1 + gzC * zC; + out[0] += aaaaC * rampValueC; + out[1] += gxC * aaaaC - 8 * rampValueC * aaaC * x1; + out[2] += gyC * aaaaC - 8 * rampValueC * aaaC * y1; + out[3] += gzC * aaaaC - 8 * rampValueC * aaaC * zC; + skipD = true; + } + } + + if(!skip5) { + double a5 = yAFlipMask1 + zAFlipMask1 + a1; + if(a5 > 0) { + double y5 = (yNMask | 1) + y1; + double z5 = (zNMask | 1) + z1; + double aa5 = a5 * a5, aaa5 = aa5 * a5, aaaa5 = aa5 * aa5; + int gi5 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + (zNMask & (PRIME_Z << 1))); + double gx5 = GRADIENTS_3D[gi5], gy5 = GRADIENTS_3D[gi5 | 1], gz5 = GRADIENTS_3D[gi5 | 2]; + double rampValue5 = gx5 * x1 + gy5 * y5 + gz5 * z5; + out[0] += aaaa5 * rampValue5; + out[1] += gx5 * aaaa5 - 8 * rampValue5 * aaa5 * x1; + out[2] += gy5 * aaaa5 - 8 * rampValue5 * aaa5 * y5; + out[3] += gz5 * aaaa5 - 8 * rampValue5 * aaa5 * z5; + } + } + + if(!skip9) { + double a9 = xAFlipMask1 + zAFlipMask1 + a1; + if(a9 > 0) { + double x9 = (xNMask | 1) + x1; + double z9 = (zNMask | 1) + z1; + double aa9 = a9 * a9, aaa9 = aa9 * a9, aaaa9 = aa9 * aa9; + int gi9 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + (zNMask & (PRIME_Z << 1))); + double gx9 = GRADIENTS_3D[gi9], gy9 = GRADIENTS_3D[gi9 | 1], gz9 = GRADIENTS_3D[gi9 | 2]; + double rampValue9 = gx9 * x9 + gy9 * y1 + gz9 * z9; + out[0] += aaaa9 * rampValue9; + out[1] += gx9 * aaaa9 - 8 * rampValue9 * aaa9 * x9; + out[2] += gy9 * aaaa9 - 8 * rampValue9 * aaa9 * y1; + out[3] += gz9 * aaaa9 - 8 * rampValue9 * aaa9 * z9; + } + } + + if(!skipD) { + double aD = xAFlipMask1 + yAFlipMask1 + a1; + if(aD > 0) { + double xD = (xNMask | 1) + x1; + double yD = (yNMask | 1) + y1; + double aaD = aD * aD, aaaD = aaD * aD, aaaaD = aaD * aaD; + int giD = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z); + double gxD = GRADIENTS_3D[giD], gyD = GRADIENTS_3D[giD | 1], gzD = GRADIENTS_3D[giD | 2]; + double rampValueD = gxD * xD + gyD * yD + gzD * z1; + out[0] += aaaaD * rampValueD; + out[1] += gxD * aaaaD - 8 * rampValueD * aaaD * xD; + out[2] += gyD * aaaaD - 8 * rampValueD * aaaD * yD; + out[3] += gzD * aaaaD - 8 * rampValueD * aaaD * z1; + } + } + + out[0] *= 9.046026385208288; + out[1] *= 9.046026385208288; + out[2] *= 9.046026385208288; + out[3] *= 9.046026385208288; + return out; + } } diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2Sampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2Sampler.java index e4da85a5bb..e86ec2234a 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2Sampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/OpenSimplex2Sampler.java @@ -37,41 +37,37 @@ public double getNoiseRaw(long sl, double x, double y) { i *= PRIME_X; j *= PRIME_Y; - double n0, n1, n2; + double value = 0; double a = 0.5 - x0 * x0 - y0 * y0; - if(a <= 0) n0 = 0; - else { - n0 = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0); + if(a > 0) { + value = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0); } double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a); - if(c <= 0) n2 = 0; - else { + if(c > 0) { double x2 = x0 + (2 * G2 - 1); double y2 = y0 + (2 * G2 - 1); - n2 = (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2); + value += (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2); } if(y0 > x0) { double x1 = x0 + G2; double y1 = y0 + (G2 - 1); double b = 0.5 - x1 * x1 - y1 * y1; - if(b <= 0) n1 = 0; - else { - n1 = (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1); + if(b > 0) { + value += (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1); } } else { double x1 = x0 + (G2 - 1); double y1 = y0 + G2; double b = 0.5 - x1 * x1 - y1 * y1; - if(b <= 0) n1 = 0; - else { - n1 = (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1); + if(b > 0) { + value += (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1); } } - return (n0 + n1 + n2) * 99.83685446303647f; + return value * 99.83685446303647f; } @Override @@ -157,4 +153,208 @@ public double getNoiseRaw(long sl, double x, double y, double z) { return value * 32.69428253173828125; } + + @Override + public boolean isDifferentiable() { + return true; + } + + @Override + public double[] getNoiseDerivativeRaw(long sl, double x, double y) { + int seed = (int) sl; + // 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex. + final double G2 = (3 - SQRT3) / 6; + + final double F2 = 0.5f * (SQRT3 - 1); + double s = (x + y) * F2; + x += s; + y += s; + + + int i = (int) Math.floor(x); + int j = (int) Math.floor(y); + double xi = x - i; + double yi = y - j; + + double t = (xi + yi) * G2; + double x0 = xi - t; + double y0 = yi - t; + + i *= PRIME_X; + j *= PRIME_Y; + + double[] out = { 0.0f, 0.0f, 0.0f }; + + double a = 0.5 - x0 * x0 - y0 * y0; + if(a > 0) { + double aa = a * a, aaa = aa * a, aaaa = aa * aa; + int gi = gradCoordIndex(seed, i, j); + double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1]; + double rampValue = gx * x0 + gy * y0; + out[0] += aaaa * rampValue; + out[1] += gx * aaaa - 8 * rampValue * aaa * x0; + out[2] += gy * aaaa - 8 * rampValue * aaa * y0; + } + + double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a); + if(c > 0) { + double x2 = x0 + (2 * G2 - 1); + double y2 = y0 + (2 * G2 - 1); + double cc = c * c, ccc = cc * c, cccc = cc * cc; + int gi = gradCoordIndex(seed, i + PRIME_X, j + PRIME_Y); + double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1]; + double rampValue = gx * x2 + gy * y2; + out[0] += cccc * rampValue; + out[1] += gx * cccc - 8 * rampValue * ccc * x2; + out[2] += gy * cccc - 8 * rampValue * ccc * y2; + } + + if(y0 > x0) { + double x1 = x0 + G2; + double y1 = y0 + (G2 - 1); + double b = 0.5 - x1 * x1 - y1 * y1; + if(b > 0) { + double bb = b * b, bbb = bb * b, bbbb = bb * bb; + int gi = gradCoordIndex(seed, i, j + PRIME_Y); + double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1]; + double rampValue = gx * x1 + gy * y1; + out[0] += bbbb * rampValue; + out[1] += gx * bbbb - 8 * rampValue * bbb * x1; + out[2] += gy * bbbb - 8 * rampValue * bbb * y1; + } + } else { + double x1 = x0 + (G2 - 1); + double y1 = y0 + G2; + double b = 0.5 - x1 * x1 - y1 * y1; + if(b > 0) { + double bb = b * b, bbb = bb * b, bbbb = bb * bb; + int gi = gradCoordIndex(seed, i + PRIME_X, j); + double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1]; + double rampValue = gx * x1 + gy * y1; + out[0] += bbbb * rampValue; + out[1] += gx * bbbb - 8 * rampValue * bbb * x1; + out[2] += gy * bbbb - 8 * rampValue * bbb * y1; + } + } + + out[0] *= 99.83685446303647f; + out[1] *= 99.83685446303647f; + out[2] *= 99.83685446303647f; + return out; + } + + @Override + public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) { + int seed = (int) sl; + // 3D OpenSimplex2Sampler case uses two offset rotated cube grids. + final double R3 = (2.0 / 3.0); + double r = (x + y + z) * R3; // Rotation, not skew + x = r - x; + y = r - y; + z = r - z; + + + int i = (int) Math.round(x); + int j = (int) Math.round(y); + int k = (int) Math.round(z); + double x0 = x - i; + double y0 = y - j; + double z0 = z - k; + + int xNSign = (int) (-1.0 - x0) | 1; + int yNSign = (int) (-1.0 - y0) | 1; + int zNSign = (int) (-1.0 - z0) | 1; + + double ax0 = xNSign * -x0; + double ay0 = yNSign * -y0; + double az0 = zNSign * -z0; + + i *= PRIME_X; + j *= PRIME_Y; + k *= PRIME_Z; + + double[] out = { 0.0f, 0.0f, 0.0f, 0.0f }; + double a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0); + + for(int l = 0; ; l++) { + if(a > 0) { + double aa = a * a, aaa = aa * a, aaaa = aa * aa; + int gi = gradCoordIndex(seed, i, j, k); + double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2]; + double rampValue = gx * x0 + gy * y0 + gz * z0; + out[0] += aaaa * rampValue; + out[1] += gx * aaaa - 8 * rampValue * aaa * x0; + out[1] += gy * aaaa - 8 * rampValue * aaa * y0; + out[2] += gz * aaaa - 8 * rampValue * aaa * z0; + } + + if(ax0 >= ay0 && ax0 >= az0) { + double b = a + ax0 + ax0; + if(b > 1) { + b -= 1; + double bb = b * b, bbb = bb * b, bbbb = bb * bb; + int gi = gradCoordIndex(seed, i - xNSign * PRIME_X, j, k); + double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2]; + double rampValue = gx * (x0 + xNSign) + gy * y0 + gz * z0; + out[0] += bbbb * rampValue; + out[1] += gx * bbbb - 8 * rampValue * bbb * (x0 + xNSign); + out[1] += gy * bbbb - 8 * rampValue * bbb * y0; + out[2] += gz * bbbb - 8 * rampValue * bbb * z0; + } + } else if(ay0 > ax0 && ay0 >= az0) { + double b = a + ay0 + ay0; + if(b > 1) { + b -= 1; + double bb = b * b, bbb = bb * b, bbbb = bb * bb; + int gi = gradCoordIndex(seed, i, j - yNSign * PRIME_Y, k); + double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2]; + double rampValue = gx * x0 + gy * (y0 + yNSign) + gz * z0; + out[0] += bbbb * rampValue; + out[1] += gx * bbbb - 8 * rampValue * bbb * x0; + out[1] += gy * bbbb - 8 * rampValue * bbb * (y0 + yNSign); + out[2] += gz * bbbb - 8 * rampValue * bbb * z0; + } + } else { + double b = a + az0 + az0; + if(b > 1) { + b -= 1; + double bb = b * b, bbb = bb * b, bbbb = bb * bb; + int gi = gradCoordIndex(seed, i, j, k - zNSign * PRIME_Z); + double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2]; + double rampValue = gx * x0 + gy * y0 + gz * (z0 + zNSign); + out[0] += bbbb * rampValue; + out[1] += gx * bbbb - 8 * rampValue * bbb * x0; + out[1] += gy * bbbb - 8 * rampValue * bbb * y0; + out[2] += gz * bbbb - 8 * rampValue * bbb * (z0 + zNSign); + } + } + + if(l == 1) break; + + ax0 = 0.5 - ax0; + ay0 = 0.5 - ay0; + az0 = 0.5 - az0; + + x0 = xNSign * ax0; + y0 = yNSign * ay0; + z0 = zNSign * az0; + + a += (0.75 - ax0) - (ay0 + az0); + + i += (xNSign >> 1) & PRIME_X; + j += (yNSign >> 1) & PRIME_Y; + k += (zNSign >> 1) & PRIME_Z; + + xNSign = -xNSign; + yNSign = -yNSign; + zNSign = -zNSign; + + seed = ~seed; + } + out[0] *= 32.69428253173828125; + out[1] *= 32.69428253173828125; + out[2] *= 32.69428253173828125; + out[3] *= 32.69428253173828125; + return out; + } } diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/PerlinSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/PerlinSampler.java index 46ca9af30b..8ce0c19dc5 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/PerlinSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/PerlinSampler.java @@ -33,10 +33,10 @@ public double getNoiseRaw(long sl, double x, double y) { int x1 = x0 + PRIME_X; int y1 = y0 + PRIME_Y; - double xf0 = MathUtil.lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs); - double xf1 = MathUtil.lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs); + double xf0 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0)); + double xf1 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1)); - return MathUtil.lerp(xf0, xf1, ys) * 1.4247691104677813; + return MathUtil.lerp(ys, xf0, xf1) * 1.4247691104677813; } @Override @@ -64,14 +64,14 @@ public double getNoiseRaw(long sl, double x, double y, double z) { int y1 = y0 + PRIME_Y; int z1 = z0 + PRIME_Z; - double xf00 = MathUtil.lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs); - double xf10 = MathUtil.lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs); - double xf01 = MathUtil.lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs); - double xf11 = MathUtil.lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs); + double xf00 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0)); + double xf10 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0)); + double xf01 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1)); + double xf11 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1)); - double yf0 = MathUtil.lerp(xf00, xf10, ys); - double yf1 = MathUtil.lerp(xf01, xf11, ys); + double yf0 = MathUtil.lerp(ys, xf00, xf10); + double yf1 = MathUtil.lerp(ys, xf01, xf11); - return MathUtil.lerp(yf0, yf1, zs) * 0.964921414852142333984375; + return MathUtil.lerp(zs, yf0, yf1) * 0.964921414852142333984375; } } diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/SimplexStyleSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/SimplexStyleSampler.java index eda599a347..f9c3f65a7a 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/SimplexStyleSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/simplex/SimplexStyleSampler.java @@ -7,13 +7,13 @@ package com.dfsek.terra.addons.noise.samplers.noise.simplex; -import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction; +import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction; /** * Abstract NoiseSampler implementation for simplex-style noise functions. */ -public abstract class SimplexStyleSampler extends NoiseFunction { +public abstract class SimplexStyleSampler extends DerivativeNoiseFunction { protected static final double[] GRADIENTS_2_D = { 0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d, 0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d, @@ -79,26 +79,53 @@ public abstract class SimplexStyleSampler extends NoiseFunction { 1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0 }; - protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) { + protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed) { int hash = hash(seed, xPrimed, yPrimed); hash ^= hash >> 15; hash &= 127 << 1; - double xg = GRADIENTS_2_D[hash]; - double yg = GRADIENTS_2_D[hash | 1]; + return hash; + } + + protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) { + int index = gradCoordIndex(seed, xPrimed, yPrimed); + + double xg = GRADIENTS_2_D[index]; + double yg = GRADIENTS_2_D[index | 1]; return xd * xg + yd * yg; } - protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) { + protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed, int zPrimed) { int hash = hash(seed, xPrimed, yPrimed, zPrimed); hash ^= hash >> 15; hash &= 63 << 2; - double xg = GRADIENTS_3D[hash]; - double yg = GRADIENTS_3D[hash | 1]; - double zg = GRADIENTS_3D[hash | 2]; + return hash; + } + + protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) { + int index = gradCoordIndex(seed, xPrimed, yPrimed, zPrimed); + + double xg = GRADIENTS_3D[index]; + double yg = GRADIENTS_3D[index | 1]; + double zg = GRADIENTS_3D[index | 2]; return xd * xg + yd * yg + zd * zg; } + + @Override + public double[] getNoiseDerivativeRaw(long seed, double x, double y) { + return new double[]{ 0, 0, 0 }; + } + + @Override + public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) { + return new double[]{ 0, 0, 0, 0 }; + } + + @Override + public boolean isDifferentiable() { + return false; + } } diff --git a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/value/ValueSampler.java b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/value/ValueSampler.java index 09b0574cf2..f0ce724036 100644 --- a/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/value/ValueSampler.java +++ b/common/addons/config-noise-function/src/main/java/com/dfsek/terra/addons/noise/samplers/noise/value/ValueSampler.java @@ -25,10 +25,10 @@ public double getNoiseRaw(long sl, double x, double y) { int x1 = x0 + PRIME_X; int y1 = y0 + PRIME_Y; - double xf0 = MathUtil.lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs); - double xf1 = MathUtil.lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs); + double xf0 = MathUtil.lerp(xs, valCoord(seed, x0, y0), valCoord(seed, x1, y0)); + double xf1 = MathUtil.lerp(xs, valCoord(seed, x0, y1), valCoord(seed, x1, y1)); - return MathUtil.lerp(xf0, xf1, ys); + return MathUtil.lerp(ys, xf0, xf1); } @Override @@ -49,14 +49,14 @@ public double getNoiseRaw(long sl, double x, double y, double z) { int y1 = y0 + PRIME_Y; int z1 = z0 + PRIME_Z; - double xf00 = MathUtil.lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs); - double xf10 = MathUtil.lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs); - double xf01 = MathUtil.lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs); - double xf11 = MathUtil.lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs); + double xf00 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0)); + double xf10 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0)); + double xf01 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1)); + double xf11 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1)); - double yf0 = MathUtil.lerp(xf00, xf10, ys); - double yf1 = MathUtil.lerp(xf01, xf11, ys); + double yf0 = MathUtil.lerp(ys, xf00, xf10); + double yf1 = MathUtil.lerp(ys, xf01, xf11); - return MathUtil.lerp(yf0, yf1, zs); + return MathUtil.lerp(zs, yf0, yf1); } } diff --git a/common/addons/config-ore/build.gradle.kts b/common/addons/config-ore/build.gradle.kts index 469635ee66..06718492e4 100644 --- a/common/addons/config-ore/build.gradle.kts +++ b/common/addons/config-ore/build.gradle.kts @@ -1,4 +1,4 @@ -version = version("1.1.0") +version = version("1.1.1") dependencies { compileOnlyApi(project(":common:addons:manifest-addon-loader")) diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java index cfef65b571..f8ede8680e 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/utils/VanillaOreUtils.java @@ -8,31 +8,24 @@ public class VanillaOreUtils { - protected static boolean shouldNotDiscard(Random random, double chance) { - if(chance <= 0.0F) { - return true; - } else if(chance >= 1.0F) { - return false; - } else { - return random.nextFloat() >= chance; - } + private static boolean shouldExpose(Random random, double exposedChance) { + if(exposedChance >= 1.0F) return true; + if(exposedChance <= 0.0F) return false; + return random.nextFloat() < exposedChance; } - public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposed, Random random, WritableWorld world, int x, + public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposedChance, Random random, WritableWorld world, + int x, int y, int z) { - if(!replaceable.contains(type)) { - return false; - } else if(shouldNotDiscard(random, exposed)) { - return true; - } else { - return !(world.getBlockState(x, y, z - 1).isAir() || - world.getBlockState(x, y, z + 1).isAir() || - world.getBlockState(x, y - 1, z).isAir() || - world.getBlockState(x, y + 1, z).isAir() || - world.getBlockState(x - 1, y, z).isAir() || - world.getBlockState(x + 1, y, z).isAir()); - } + if(!replaceable.contains(type)) return false; + if(shouldExpose(random, exposedChance)) return true; // Exposed blocks can be placed regardless of adjacency to air + // Adjacency is checked after determining not exposed rather than vice-versa, assuming block checks are more expensive + boolean adjacentAir = world.getBlockState(x, y, z - 1).isAir() || + world.getBlockState(x, y, z + 1).isAir() || + world.getBlockState(x, y - 1, z).isAir() || + world.getBlockState(x, y + 1, z).isAir() || + world.getBlockState(x - 1, y, z).isAir() || + world.getBlockState(x + 1, y, z).isAir(); + return !adjacentAir; // Exposed check did not pass earlier so only blocks not adjacent air should place } - } - diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java index 41009ed0b5..f1ca7d9456 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationAddon.java @@ -11,13 +11,6 @@ import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Supplier; - import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures; import com.dfsek.terra.addons.generation.feature.config.FeatureStageTemplate; import com.dfsek.terra.addons.manifest.api.AddonInitializer; @@ -35,6 +28,9 @@ import com.dfsek.terra.api.world.biome.Biome; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; +import java.util.*; +import java.util.function.Supplier; + public class FeatureGenerationAddon implements AddonInitializer { public static final TypeKey>> STAGE_TYPE_KEY = new TypeKey<>() { diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java index 6baf88b7a0..132889d237 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -7,11 +7,9 @@ package com.dfsek.terra.addons.generation.feature; -import java.util.Collections; -import java.util.Random; - import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures; import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.properties.PropertyKey; import com.dfsek.terra.api.registry.key.StringIdentifiable; import com.dfsek.terra.api.util.Rotation; @@ -21,6 +19,9 @@ import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; import com.dfsek.terra.api.world.chunk.generation.util.Column; +import java.util.Collections; +import java.util.Random; + public class FeatureGenerationStage implements GenerationStage, StringIdentifiable { private final Platform platform; @@ -31,13 +32,20 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab private final int resolution; private final PropertyKey biomeFeaturesKey; + private final NoiseSampler blendSampler; + private final boolean doBlending; + private final double blendAmplitude; - public FeatureGenerationStage(Platform platform, String id, int resolution, PropertyKey biomeFeaturesKey) { + public FeatureGenerationStage(Platform platform, String id, int resolution, PropertyKey biomeFeaturesKey, + NoiseSampler blendSampler, double blendAmplitude) { this.platform = platform; this.id = id; this.profile = "feature_stage:" + id; this.resolution = resolution; this.biomeFeaturesKey = biomeFeaturesKey; + this.blendSampler = blendSampler; + this.doBlending = blendAmplitude != 0d; + this.blendAmplitude = blendAmplitude; } @Override @@ -52,7 +60,10 @@ public void populate(ProtoWorld world) { int tx = cx + chunkX; int tz = cz + chunkZ; world.getBiomeProvider() - .getColumn(tx, tz, world) + .getColumn( + tx + (doBlending ? (int) (blendSampler.noise(seed, tx, tz) * blendAmplitude) : 0), + tz + (doBlending ? (int) (blendSampler.noise(seed + 1, tx, tz) * blendAmplitude) : 0), + world) .forRanges(resolution, (min, max, biome) -> { for(int subChunkX = 0; subChunkX < resolution; subChunkX++) { for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) { diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java index ffc077f1a8..d0fae0e1f2 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/config/FeatureStageTemplate.java @@ -8,6 +8,7 @@ import com.dfsek.terra.addons.generation.feature.FeatureGenerationStage; import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.properties.PropertyKey; import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage; @@ -22,6 +23,24 @@ public class FeatureStageTemplate implements ObjectTemplate, Va @Default private int resolution = 4; + @Value("blend.sampler") + @Default + private NoiseSampler blendSampler = new NoiseSampler() { + @Override + public double noise(long seed, double x, double y) { + return 0; + } + + @Override + public double noise(long seed, double x, double y, double z) { + return 0; + } + }; + + @Value("blend.amplitude") + @Default + private double blendAmplitude = 0d; + public FeatureStageTemplate(Platform platform, PropertyKey biomeFeaturesKey) { this.platform = platform; this.biomeFeaturesKey = biomeFeaturesKey; @@ -30,7 +49,7 @@ public FeatureStageTemplate(Platform platform, PropertyKey biomeF @Override public FeatureGenerationStage get() { - return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey); + return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey, blendSampler, blendAmplitude); } @Override diff --git a/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java b/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java index 30b2d59844..5b18dd0639 100644 --- a/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java +++ b/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java @@ -1,7 +1,5 @@ package com.dfsek.terra.addons.structure.mutator; -import java.util.Random; - import com.dfsek.terra.api.registry.key.Keyed; import com.dfsek.terra.api.registry.key.RegistryKey; import com.dfsek.terra.api.structure.Structure; @@ -11,6 +9,8 @@ import com.dfsek.terra.api.world.util.ReadInterceptor; import com.dfsek.terra.api.world.util.WriteInterceptor; +import java.util.Random; + public class MutatedStructure implements Structure, Keyed { private final RegistryKey key; diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/CheckBlockFunctionBuilder.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/CheckBlockFunctionBuilder.java index 588b99f53f..cfef3f5728 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/CheckBlockFunctionBuilder.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/CheckBlockFunctionBuilder.java @@ -7,13 +7,13 @@ package com.dfsek.terra.addons.terrascript.script.builders; -import java.util.List; - import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; import com.dfsek.terra.addons.terrascript.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.addons.terrascript.script.functions.CheckBlockFunction; import com.dfsek.terra.addons.terrascript.tokenizer.Position; +import java.util.List; + public class CheckBlockFunctionBuilder implements FunctionBuilder { @SuppressWarnings("unchecked") diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java index c4518b47c3..28de644816 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/BlockFunction.java @@ -10,8 +10,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments; import com.dfsek.terra.addons.terrascript.parser.lang.Returnable; @@ -32,7 +32,7 @@ public class BlockFunction implements Function { protected final Returnable x, y, z; protected final Returnable blockData; protected final Platform platform; - private final Map data = new HashMap<>(); + private final Map data = new ConcurrentHashMap<>(); private final Returnable overwrite; private final Returnable physics; private final Position position; diff --git a/common/api/build.gradle.kts b/common/api/build.gradle.kts index 68a2f0d757..898f8bdcd6 100644 --- a/common/api/build.gradle.kts +++ b/common/api/build.gradle.kts @@ -2,10 +2,10 @@ dependencies { api("ca.solo-studios", "strata", Versions.Libraries.strata) compileOnlyApi("org.slf4j", "slf4j-api", Versions.Libraries.slf4j) testImplementation("org.slf4j", "slf4j-api", Versions.Libraries.slf4j) - api("cloud.commandframework", "cloud-core", Versions.Libraries.cloud) + api("org.incendo", "cloud-core", Versions.Libraries.cloud) api("com.dfsek.tectonic", "common", Versions.Libraries.tectonic) - api("com.github.ben-manes.caffeine:caffeine:3.1.0") + api("com.github.ben-manes.caffeine", "caffeine", Versions.Libraries.caffeine) } \ No newline at end of file diff --git a/common/api/src/main/java/com/dfsek/terra/api/command/arguments/RegistryArgument.java b/common/api/src/main/java/com/dfsek/terra/api/command/arguments/RegistryArgument.java index e89298751e..8e15c18ceb 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/command/arguments/RegistryArgument.java +++ b/common/api/src/main/java/com/dfsek/terra/api/command/arguments/RegistryArgument.java @@ -1,18 +1,19 @@ package com.dfsek.terra.api.command.arguments; -import cloud.commandframework.ArgumentDescription; -import cloud.commandframework.arguments.CommandArgument; -import cloud.commandframework.arguments.parser.ArgumentParseResult; -import cloud.commandframework.arguments.parser.ArgumentParser; -import cloud.commandframework.context.CommandContext; import io.leangen.geantyref.TypeToken; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.incendo.cloud.component.CommandComponent; +import org.incendo.cloud.component.DefaultValue; +import org.incendo.cloud.context.CommandContext; +import org.incendo.cloud.context.CommandInput; +import org.incendo.cloud.parser.ArgumentParseResult; +import org.incendo.cloud.parser.ArgumentParser; +import org.incendo.cloud.parser.ParserDescriptor; +import org.incendo.cloud.suggestion.Suggestion; +import org.incendo.cloud.suggestion.SuggestionProvider; -import java.util.List; import java.util.Optional; -import java.util.Queue; -import java.util.function.BiFunction; +import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.stream.Collectors; @@ -22,39 +23,22 @@ import com.dfsek.terra.api.util.reflection.TypeKey; -public class RegistryArgument extends CommandArgument { - private RegistryArgument( - boolean required, - @NonNull String name, - Function, Registry> registryFunction, - TypeToken typeToken, - @NonNull String defaultValue, - @Nullable BiFunction, String, List> suggestionsProvider, - @NonNull ArgumentDescription description - ) { - super(required, - name, - new RegistryArgumentParser<>(registryFunction), - defaultValue, - typeToken, - suggestionsProvider, - description); - } +public class RegistryArgument { public static Builder builder(String name, Registry registry) { return new Builder<>(name, registry); } - public static CommandArgument of(String name, Registry registry) { + public static CommandComponent of(String name, Registry registry) { return RegistryArgument.builder(name, registry).build(); } - public static CommandArgument optional(String name, Registry registry) { - return RegistryArgument.builder(name, registry).asOptional().build(); + public static CommandComponent optional(String name, Registry registry) { + return RegistryArgument.builder(name, registry).optional().build(); } - public static CommandArgument optional(String name, Registry registry, String defaultKey) { - return RegistryArgument.builder(name, registry).asOptionalWithDefault(defaultKey).build(); + public static CommandComponent optional(String name, Registry registry, DefaultValue defaultKey) { + return RegistryArgument.builder(name, registry).optional(defaultKey).build(); } @SuppressWarnings("unchecked") @@ -63,49 +47,36 @@ public static Builder builder(String name, Function(name, registryFunction, (TypeToken) TypeToken.get(registryType.getType())); } - public static CommandArgument of(String name, Function, Registry> registryFunction, - TypeKey registryType) { + public static CommandComponent of(String name, Function, Registry> registryFunction, + TypeKey registryType) { return RegistryArgument.builder(name, registryFunction, registryType).build(); } - public static CommandArgument optional(String name, Function, Registry> registryFunction, - TypeKey registryType) { - return RegistryArgument.builder(name, registryFunction, registryType).asOptional().build(); + public static CommandComponent optional(String name, Function, Registry> registryFunction, + TypeKey registryType) { + return RegistryArgument.builder(name, registryFunction, registryType).optional().build(); } - public static CommandArgument optional(String name, Function, Registry> registryFunction, - TypeKey registryType, String defaultKey) { - return RegistryArgument.builder(name, registryFunction, registryType).asOptionalWithDefault(defaultKey).build(); + public static CommandComponent optional(String name, Function, Registry> registryFunction, + TypeKey registryType, DefaultValue defaultKey) { + return RegistryArgument.builder(name, registryFunction, registryType).optional(defaultKey).build(); } - public static final class Builder extends CommandArgument.Builder { - private final Function, Registry> registryFunction; - private final TypeToken typeToken; + public static final class Builder extends CommandComponent.Builder { @SuppressWarnings("unchecked") private Builder(@NonNull String name, Registry registry) { - super((TypeToken) TypeToken.get(registry.getType().getType()), name); - this.registryFunction = commandContext -> registry; - this.typeToken = (TypeToken) TypeToken.get(registry.getType().getType()); + super(); + this.name(name); + this.parser(ParserDescriptor.of( + new RegistryArgumentParser<>(commandContext -> registry), + (TypeToken) TypeToken.get(registry.getType().getType()))); } private Builder(@NonNull String name, Function, Registry> registryFunction, TypeToken typeToken) { - super(typeToken, name); - this.typeToken = typeToken; - this.registryFunction = registryFunction; - } - - @Override - public @NonNull RegistryArgument build() { - return new RegistryArgument<>( - isRequired(), - getName(), - registryFunction, - typeToken, - getDefaultValue(), - getSuggestionsProvider(), - getDefaultDescription() - ); + super(); + this.name(name); + this.parser(ParserDescriptor.of(new RegistryArgumentParser<>(registryFunction), typeToken)); } } @@ -119,12 +90,12 @@ private RegistryArgumentParser(Function, Registry> registry @Override public @NonNull ArgumentParseResult<@NonNull R> parse(@NonNull CommandContext<@NonNull T> commandContext, - @NonNull Queue<@NonNull String> inputQueue) { - String input = inputQueue.remove(); - String next = inputQueue.peek(); - if(next != null && next.equals(":")) { - input += inputQueue.remove(); - input += inputQueue.remove(); + @NonNull CommandInput commandInput) { + String input = commandInput.readString(); + String next = commandInput.peekString(); + if(next.equals(":")) { + input += commandInput.readString(); + input += commandInput.readString(); } Registry registry = registryFunction.apply(commandContext); @@ -146,8 +117,17 @@ private RegistryArgumentParser(Function, Registry> registry } @Override - public @NonNull List<@NonNull String> suggestions(@NonNull CommandContext commandContext, @NonNull String input) { - return registryFunction.apply(commandContext).keys().stream().map(RegistryKey::toString).sorted().collect(Collectors.toList()); + public @NonNull SuggestionProvider suggestionProvider() { + return new SuggestionProvider<>() { + @Override + public @NonNull CompletableFuture> suggestionsFuture( + @NonNull CommandContext context, @NonNull CommandInput input) { + + // TODO: Verify whether this is correct + return CompletableFuture.completedFuture(registryFunction.apply(context).keys().stream().map( + registryKey -> Suggestion.suggestion(registryKey.toString())).sorted().collect(Collectors.toList())); + } + }; } } } diff --git a/common/api/src/main/java/com/dfsek/terra/api/event/events/platform/CommandRegistrationEvent.java b/common/api/src/main/java/com/dfsek/terra/api/event/events/platform/CommandRegistrationEvent.java index de13f061a2..3ad041c9bd 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/event/events/platform/CommandRegistrationEvent.java +++ b/common/api/src/main/java/com/dfsek/terra/api/event/events/platform/CommandRegistrationEvent.java @@ -1,10 +1,10 @@ package com.dfsek.terra.api.event.events.platform; -import cloud.commandframework.CommandManager; - import com.dfsek.terra.api.command.CommandSender; import com.dfsek.terra.api.event.events.Event; +import org.incendo.cloud.CommandManager; + public class CommandRegistrationEvent implements Event { private final CommandManager commandManager; diff --git a/common/api/src/main/java/com/dfsek/terra/api/noise/DerivativeNoiseSampler.java b/common/api/src/main/java/com/dfsek/terra/api/noise/DerivativeNoiseSampler.java new file mode 100644 index 0000000000..f9e40f0ea5 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/noise/DerivativeNoiseSampler.java @@ -0,0 +1,45 @@ +package com.dfsek.terra.api.noise; + +/** + * A NoiseSampler which additionally may provide a 1st directional derivative + */ +public interface DerivativeNoiseSampler extends NoiseSampler { + + static boolean isDifferentiable(NoiseSampler sampler) { + if(sampler instanceof DerivativeNoiseSampler dSampler) { + return dSampler.isDifferentiable(); + } + return false; + } + + /** + * Samplers may or may not be able to provide a derivative depending on what + * inputs they take, this method signals whether this is the case. + * + * @return If the noise sampler provides a derivative or not + */ + boolean isDifferentiable(); + + /** + * Derivative return version of standard 2D noise evaluation + * + * @param seed + * @param x + * @param y + * + * @return 3 element array, in index order: noise value, partial x derivative, partial y derivative + */ + double[] noised(long seed, double x, double y); + + /** + * Derivative return version of standard 3D noise evaluation + * + * @param seed + * @param x + * @param y + * @param z + * + * @return 4 element array, in index order: noise value, partial x derivative, partial y derivative, partial z derivative + */ + double[] noised(long seed, double x, double y, double z); +} diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/reflection/ReflectionUtil.java b/common/api/src/main/java/com/dfsek/terra/api/util/reflection/ReflectionUtil.java index 8e35c3f9f3..2583b9ab6b 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/reflection/ReflectionUtil.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/reflection/ReflectionUtil.java @@ -8,6 +8,7 @@ package com.dfsek.terra.api.util.reflection; import org.jetbrains.annotations.NotNull; +import sun.misc.Unsafe; import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; @@ -26,6 +27,18 @@ public final class ReflectionUtil { + private static final Unsafe UNSAFE; + + static { + try { + final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + UNSAFE = (Unsafe) unsafeField.get(null); + } catch(NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + public static Field[] getFields(@NotNull Class type) { Field[] result = type.getDeclaredFields(); Class parentClass = type.getSuperclass(); @@ -35,6 +48,14 @@ public static Field[] getFields(@NotNull Class type) { return result; } + public static void setFinalField(Object obj, String fieldName, Object value) throws NoSuchFieldException { + Field field = obj.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + long fieldOffset = UNSAFE.objectFieldOffset(field); + + UNSAFE.putObject(obj, fieldOffset, value); + } + public static Method[] getMethods(@NotNull Class type) { Method[] result = type.getDeclaredMethods(); Class parentClass = type.getSuperclass(); diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java index 948db5f188..d49d757525 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/GenericLoaders.java @@ -31,10 +31,14 @@ import com.dfsek.terra.api.util.Range; import com.dfsek.terra.api.util.collection.MaterialSet; import com.dfsek.terra.api.util.collection.ProbabilityCollection; +import com.dfsek.terra.api.util.vector.Vector3; +import com.dfsek.terra.api.util.vector.Vector3Int; import com.dfsek.terra.config.loaders.LinkedHashMapLoader; import com.dfsek.terra.config.loaders.MaterialSetLoader; import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader; import com.dfsek.terra.config.loaders.RangeLoader; +import com.dfsek.terra.config.loaders.Vector3IntLoader; +import com.dfsek.terra.config.loaders.Vector3Loader; import com.dfsek.terra.config.loaders.VersionLoader; import com.dfsek.terra.config.loaders.VersionRangeLoader; @@ -49,12 +53,14 @@ public GenericLoaders(Platform platform) { @Override public void register(TypeRegistry registry) { registry.registerLoader(ProbabilityCollection.class, new ProbabilityCollectionLoader()) - .registerLoader(Range.class, new RangeLoader()) - .registerLoader(Version.class, new VersionLoader()) - .registerLoader(MaterialSet.class, new MaterialSetLoader()) - .registerLoader(VersionRange.class, new VersionRangeLoader()) - .registerLoader(LinkedHashMap.class, new LinkedHashMapLoader()); - + .registerLoader(Range.class, new RangeLoader()) + .registerLoader(Version.class, new VersionLoader()) + .registerLoader(MaterialSet.class, new MaterialSetLoader()) + .registerLoader(VersionRange.class, new VersionRangeLoader()) + .registerLoader(LinkedHashMap.class, new LinkedHashMapLoader()) + .registerLoader(Vector3.class, new Vector3Loader()) + .registerLoader(Vector3Int.class, new Vector3IntLoader()); + if(platform != null) { registry.registerLoader(BaseAddon.class, platform.getAddons()) .registerLoader(BlockType.class, (type, object, configLoader, depthTracker) -> platform diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java new file mode 100644 index 0000000000..06d470594e --- /dev/null +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3IntLoader.java @@ -0,0 +1,31 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.List; +import java.util.Map; + +import com.dfsek.terra.api.util.vector.Vector3Int; + +public class Vector3IntLoader implements TypeLoader { + + @SuppressWarnings("unchecked") + @Override + public Vector3Int load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + if (o instanceof List) { + List list = (List) o; + return Vector3Int.of(list.get(0), list.get(1), list.get(2)); + } + else { + Map map = (Map) o; + return Vector3Int.of(map.get("x"), map.get("y"), map.get("z")); + } + } +} + diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java new file mode 100644 index 0000000000..cdfffe15ad --- /dev/null +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/loaders/Vector3Loader.java @@ -0,0 +1,32 @@ +package com.dfsek.terra.config.loaders; + +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.List; +import java.util.Map; + +import com.dfsek.terra.api.util.vector.Vector3; + + +public class Vector3Loader implements TypeLoader { + + @SuppressWarnings("unchecked") + @Override + public Vector3 load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + if (o instanceof List) { + List list = (List) o; + return Vector3.of(list.get(0), list.get(1), list.get(2)); + } + else { + Map map = (Map) o; + return Vector3.of(map.get("x"), map.get("y"), map.get("z")); + } + } +} + diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java index 06b617cd80..82ec7d95b5 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java @@ -26,6 +26,33 @@ import com.dfsek.tectonic.api.loader.ConfigLoader; import com.dfsek.tectonic.api.loader.type.TypeLoader; import com.dfsek.tectonic.yaml.YamlConfiguration; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimaps; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.addon.BaseAddon; @@ -56,28 +83,16 @@ import com.dfsek.terra.config.fileloaders.ZIPLoader; import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader; import com.dfsek.terra.config.loaders.config.BufferedImageLoader; -import com.dfsek.terra.config.preprocessor.*; +import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor; +import com.dfsek.terra.config.preprocessor.MetaMapPreprocessor; +import com.dfsek.terra.config.preprocessor.MetaNumberPreprocessor; +import com.dfsek.terra.config.preprocessor.MetaStringPreprocessor; +import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor; import com.dfsek.terra.config.prototype.ProtoConfig; import com.dfsek.terra.registry.CheckedRegistryImpl; import com.dfsek.terra.registry.OpenRegistryImpl; import com.dfsek.terra.registry.ShortcutHolder; -import com.google.common.collect.ListMultimap; -import com.google.common.collect.Multimaps; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.awt.image.BufferedImage; -import java.io.*; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - /** * Represents a Terra configuration pack. diff --git a/common/implementation/base/src/main/java/com/dfsek/terra/config/preprocessor/MetaNumberPreprocessor.java b/common/implementation/base/src/main/java/com/dfsek/terra/config/preprocessor/MetaNumberPreprocessor.java index 9197adeb1e..c823d7ec44 100644 --- a/common/implementation/base/src/main/java/com/dfsek/terra/config/preprocessor/MetaNumberPreprocessor.java +++ b/common/implementation/base/src/main/java/com/dfsek/terra/config/preprocessor/MetaNumberPreprocessor.java @@ -24,14 +24,15 @@ import com.dfsek.tectonic.api.exception.LoadException; import com.dfsek.tectonic.api.loader.ConfigLoader; import com.dfsek.tectonic.api.preprocessor.Result; + +import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.api.util.reflection.TypeKey; + import org.jetbrains.annotations.NotNull; import java.lang.reflect.AnnotatedType; import java.util.Map; -import com.dfsek.terra.api.config.meta.Meta; -import com.dfsek.terra.api.util.reflection.TypeKey; - public class MetaNumberPreprocessor extends MetaPreprocessor { public static final TypeKey META_STRING_KEY = new TypeKey<@Meta String>() { diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49..e6441136f3 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ac72c34e8a..8e876e1c55 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 0adc8e1a53..b740cf1339 100755 --- a/gradlew +++ b/gradlew @@ -55,7 +55,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -202,11 +202,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f13..25da30dbde 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/platforms/bukkit/build.gradle.kts b/platforms/bukkit/build.gradle.kts index 89df67efcf..08a75dc125 100644 --- a/platforms/bukkit/build.gradle.kts +++ b/platforms/bukkit/build.gradle.kts @@ -2,27 +2,15 @@ plugins { id("xyz.jpenilla.run-paper") version Versions.Bukkit.runPaper } -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") { - name = "Sonatype" - } -} - dependencies { shaded(project(":platforms:bukkit:common")) - shaded(project(":platforms:bukkit:nms:v1_18_R2", configuration = "reobf")) - shaded(project(":platforms:bukkit:nms:v1_19_R1", configuration = "reobf")) - shaded(project(":platforms:bukkit:nms:v1_19_R2", configuration = "reobf")) - shaded(project(":platforms:bukkit:nms:v1_19_R3", configuration = "reobf")) - shaded(project(":platforms:bukkit:nms:v1_20_R1", configuration = "reobf")) - shaded(project(":platforms:bukkit:nms:v1_20_R2", configuration = "reobf")) + shaded(project(":platforms:bukkit:nms:v1_21", configuration = "reobf")) shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) } tasks { shadowJar { relocate("io.papermc.lib", "com.dfsek.terra.lib.paperlib") - relocate("com.tcoded.folialib", "com.dfsek.terra.lib.folialib") relocate("com.google.common", "com.dfsek.terra.lib.google.common") relocate("org.apache.logging.slf4j", "com.dfsek.terra.lib.slf4j-over-log4j") exclude("org/slf4j/**") diff --git a/platforms/bukkit/common/build.gradle.kts b/platforms/bukkit/common/build.gradle.kts index 1324e038d6..eaf1956cbe 100644 --- a/platforms/bukkit/common/build.gradle.kts +++ b/platforms/bukkit/common/build.gradle.kts @@ -8,10 +8,8 @@ dependencies { compileOnly("io.papermc.paper", "paper-api", Versions.Bukkit.paper) shadedApi("io.papermc", "paperlib", Versions.Bukkit.paperLib) - // TODO: 2023-11-08 When we drop support for 1.18 and 1.19, we can remove FoliaLib and instead use `RegionScheduler`, - // AsyncScheduler, or GlobalRegionScheduler. - shadedApi("com.tcoded", "FoliaLib", Versions.Bukkit.foliaLib) + shadedApi("com.google.guava", "guava", Versions.Libraries.Internal.guava) - shadedApi("cloud.commandframework", "cloud-paper", Versions.Libraries.cloud) + shadedApi("org.incendo", "cloud-paper", Versions.Libraries.cloudPaper) } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java index 0ef6164d81..45a82c5cbb 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/PlatformImpl.java @@ -84,8 +84,8 @@ public boolean reload() { } @Override - public void runPossiblyUnsafeTask(@NotNull Runnable task) { - plugin.getFoliaLib().getImpl().runAsync(task); + public void runPossiblyUnsafeTask(@NotNull Runnable runnable) { + plugin.getGlobalRegionScheduler().run(plugin, task -> runnable.run()); } @Override diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java index dd910d48cd..e3bc1d8376 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/TerraBukkitPlugin.java @@ -17,14 +17,16 @@ package com.dfsek.terra.bukkit; -import cloud.commandframework.brigadier.CloudBrigadierManager; -import cloud.commandframework.bukkit.CloudBukkitCapabilities; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.paper.PaperCommandManager; -import com.tcoded.folialib.FoliaLib; +import io.papermc.paper.threadedregions.scheduler.AsyncScheduler; +import io.papermc.paper.threadedregions.scheduler.GlobalRegionScheduler; import org.bukkit.Bukkit; import org.bukkit.generator.ChunkGenerator; import org.bukkit.plugin.java.JavaPlugin; +import org.incendo.cloud.SenderMapper; +import org.incendo.cloud.brigadier.CloudBrigadierManager; +import org.incendo.cloud.bukkit.CloudBukkitCapabilities; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.paper.LegacyPaperCommandManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -32,6 +34,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeUnit; import com.dfsek.terra.api.command.CommandSender; import com.dfsek.terra.api.config.ConfigPack; @@ -51,7 +54,9 @@ public class TerraBukkitPlugin extends JavaPlugin { private final PlatformImpl platform = new PlatformImpl(this); private final Map generatorMap = new HashMap<>(); - private final FoliaLib foliaLib = new FoliaLib(this); + private AsyncScheduler asyncScheduler = this.getServer().getAsyncScheduler(); + + private GlobalRegionScheduler globalRegionScheduler = this.getServer().getGlobalRegionScheduler(); @Override public void onEnable() { @@ -61,16 +66,20 @@ public void onEnable() { platform.getEventManager().callEvent(new PlatformInitializationEvent()); + if(!Initializer.init(platform)) { + Bukkit.getPluginManager().disablePlugin(this); + return; + } try { - PaperCommandManager commandManager = getCommandSenderPaperCommandManager(); + LegacyPaperCommandManager commandManager = getCommandSenderPaperCommandManager(); platform.getEventManager().callEvent(new CommandRegistrationEvent(commandManager)); } catch(Exception e) { // This should never happen. logger.error(""" TERRA HAS BEEN DISABLED - + Errors occurred while registering commands. Please report this to Terra. """.strip(), e); @@ -80,27 +89,29 @@ public void onEnable() { Bukkit.getPluginManager().registerEvents(new CommonListener(), this); // Register master event listener PaperUtil.checkPaper(this); - - Initializer.init(platform); } @NotNull - private PaperCommandManager getCommandSenderPaperCommandManager() throws Exception { - PaperCommandManager commandManager = new PaperCommandManager<>(this, - CommandExecutionCoordinator.simpleCoordinator(), - BukkitAdapter::adapt, - BukkitAdapter::adapt); + private LegacyPaperCommandManager getCommandSenderPaperCommandManager() throws Exception { + // TODO: Update to PaperCommandManager + LegacyPaperCommandManager commandManager = new LegacyPaperCommandManager<>( + this, + ExecutionCoordinator.simpleCoordinator(), + SenderMapper.create( + BukkitAdapter::adapt, + BukkitAdapter::adapt + )); + if(commandManager.hasCapability(CloudBukkitCapabilities.NATIVE_BRIGADIER)) { commandManager.registerBrigadier(); final CloudBrigadierManager brigManager = commandManager.brigadierManager(); if(brigManager != null) { brigManager.setNativeNumberSuggestions(false); } - } - - if(commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { + } else if(commandManager.hasCapability(CloudBukkitCapabilities.ASYNCHRONOUS_COMPLETION)) { commandManager.registerAsynchronousCompletions(); } + return commandManager; } @@ -116,6 +127,9 @@ private boolean doVersionCheck() { if(!VersionUtil.getSpigotVersionInfo().isSpigot()) logger.error("YOU ARE RUNNING A CRAFTBUKKIT OR BUKKIT SERVER. PLEASE UPGRADE TO PAPER."); + if(!VersionUtil.getSpigotVersionInfo().isPaper()) + logger.error("YOU ARE RUNNING A SPIGOT SERVER. PLEASE UPGRADE TO PAPER."); + if(VersionUtil.getSpigotVersionInfo().isMohist()) { if(System.getProperty("IKnowMohistCausesLotsOfIssuesButIWillUseItAnyways") == null) { Runnable runnable = () -> { // scary big block of text @@ -159,7 +173,7 @@ private boolean doVersionCheck() { """.strip()); }; runnable.run(); - foliaLib.getImpl().runLaterAsync(runnable, 200L); + asyncScheduler.runDelayed(this, task -> runnable.run(), 200L, TimeUnit.SECONDS); // Bukkit.shutdown(); // we're not *that* evil Bukkit.getPluginManager().disablePlugin(this); return false; @@ -167,7 +181,7 @@ private boolean doVersionCheck() { logger.warn(""" You are using Mohist, so we will not give you any support for issues that may arise. Since you enabled the "IKnowMohistCausesLotsOfIssuesButIWillUseItAnyways" flag, we won't disable Terra. But be warned. - + > I felt a great disturbance in the JVM, as if millions of plugins suddenly cried out in stack traces and were suddenly silenced. > I fear something terrible has happened. > - Astrash @@ -180,6 +194,7 @@ private boolean doVersionCheck() { @Override public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) { + if(id == null || id.trim().equals("")) { return null; } return new BukkitChunkGeneratorWrapper(generatorMap.computeIfAbsent(worldName, name -> { ConfigPack pack = platform.getConfigRegistry().getByID(id).orElseThrow( () -> new IllegalArgumentException("No such config pack \"" + id + "\"")); @@ -187,7 +202,11 @@ ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, String id) { }), platform.getRawConfigRegistry().getByID(id).orElseThrow(), platform.getWorldHandle().air()); } - public FoliaLib getFoliaLib() { - return foliaLib; + public AsyncScheduler getAsyncScheduler() { + return asyncScheduler; + } + + public GlobalRegionScheduler getGlobalRegionScheduler() { + return globalRegionScheduler; } } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java index d28798518e..35922cab5c 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/handles/BukkitWorldHandle.java @@ -20,17 +20,18 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.jetbrains.annotations.NotNull; - -import java.util.Locale; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.entity.EntityType; import com.dfsek.terra.api.handle.WorldHandle; +import com.dfsek.terra.bukkit.util.BukkitUtils; import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; -import com.dfsek.terra.bukkit.world.entity.BukkitEntityType; public class BukkitWorldHandle implements WorldHandle { + private static final Logger logger = LoggerFactory.getLogger(BukkitWorldHandle.class); private final BlockState air; public BukkitWorldHandle() { @@ -39,6 +40,13 @@ public BukkitWorldHandle() { @Override public synchronized @NotNull BlockState createBlockState(@NotNull String data) { + if(data.equals("minecraft:grass")) { //TODO: remove in 7.0 + data = "minecraft:short_grass"; + logger.warn( + "Translating minecraft:grass to minecraft:short_grass. In 1.20.3 minecraft:grass was renamed to minecraft:short_grass" + + ". You are advised to perform this rename in your config backs as this translation will be removed in the next major " + + "version of Terra."); + } org.bukkit.block.data.BlockData bukkitData = Bukkit.createBlockData( data); // somehow bukkit managed to make this not thread safe! :) return BukkitBlockState.newInstance(bukkitData); @@ -51,14 +59,6 @@ public BukkitWorldHandle() { @Override public @NotNull EntityType getEntity(@NotNull String id) { - if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id); - String entityID = id.toUpperCase(Locale.ROOT).substring(10); - - return new BukkitEntityType(switch(entityID) { - case "END_CRYSTAL" -> org.bukkit.entity.EntityType.ENDER_CRYSTAL; - case "ENDER_CRYSTAL" -> throw new IllegalArgumentException( - "Invalid entity identifier " + id); // make sure this issue can't happen the other way around. - default -> org.bukkit.entity.EntityType.valueOf(entityID); - }); + return BukkitUtils.getEntityType(id); } } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/nms/Initializer.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/nms/Initializer.java index d2ae2f04b8..fc28e4bc38 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/nms/Initializer.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/nms/Initializer.java @@ -1,20 +1,25 @@ package com.dfsek.terra.bukkit.nms; -import org.bukkit.Bukkit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.dfsek.terra.bukkit.PlatformImpl; +import com.dfsek.terra.bukkit.util.VersionUtil; public interface Initializer { - String NMS = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + String NMS = VersionUtil.getMinecraftVersionInfo().toString().replace(".", "_"); String TERRA_PACKAGE = Initializer.class.getPackageName(); - static void init(PlatformImpl platform) { + static boolean init(PlatformImpl platform) { Logger logger = LoggerFactory.getLogger(Initializer.class); try { - Class initializerClass = Class.forName(TERRA_PACKAGE + "." + NMS + ".NMSInitializer"); + String packageVersion = NMS; + if(NMS.equals("v1_21_1")) { + packageVersion = "v1_21"; + } + + Class initializerClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSInitializer"); try { Initializer initializer = (Initializer) initializerClass.getConstructor().newInstance(); initializer.initialize(platform); @@ -24,16 +29,27 @@ static void init(PlatformImpl platform) { } catch(ClassNotFoundException e) { logger.error("NMS bindings for version {} do not exist. Support for this version is limited.", NMS); logger.error("This is usually due to running Terra on an unsupported Minecraft version."); - logger.error(""); - logger.error(""); - for(int i = 0; i < 20; i++) { - logger.error("PROCEEDING WITH AN EXISTING TERRA WORLD WILL RESULT IN CORRUPTION!!!"); + String bypassKey = "IKnowThereAreNoNMSBindingsFor" + NMS + "ButIWillProceedAnyway"; + if(System.getProperty(bypassKey) == null) { + logger.error("Because of this **TERRA HAS BEEN DISABLED**."); + logger.error("Do not come ask us why it is not working."); + logger.error("If you wish to proceed anyways, you can add the JVM System Property \"{}\" to enable the plugin.", bypassKey); + return false; + } else { + logger.error(""); + logger.error(""); + for(int i = 0; i < 20; i++) { + logger.error("PROCEEDING WITH AN EXISTING TERRA WORLD WILL RESULT IN CORRUPTION!!!"); + } + logger.error(""); + logger.error(""); + logger.error("NMS bindings for version {} do not exist. Support for this version is limited.", NMS); + logger.error("This is usually due to running Terra on an unsupported Minecraft version."); + logger.error("We will not give you any support for issues that may arise."); + logger.error("Since you enabled the \"{}\" flag, we won't disable Terra. But be warned.", bypassKey); } - logger.error(""); - logger.error(""); - logger.error("NMS bindings for version {} do not exist. Support for this version is limited.", NMS); - logger.error("This is usually due to running Terra on an unsupported Minecraft version."); } + return true; } void initialize(PlatformImpl plugin); diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java index cc2fa78ef3..6c0a9c7f4d 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/BukkitUtils.java @@ -2,11 +2,40 @@ import org.bukkit.Material; import org.bukkit.block.data.BlockData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Locale; + +import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.bukkit.world.entity.BukkitEntityType; public class BukkitUtils { + private static final Logger logger = LoggerFactory.getLogger(BukkitUtils.class); + public static boolean isLiquid(BlockData blockState) { Material material = blockState.getMaterial(); return material == Material.WATER || material == Material.LAVA; } + + public static EntityType getEntityType(String id) { + if(!id.contains(":")) { //TODO: remove in 7.0 + String newid = "minecraft:" + id.toLowerCase(); + ; + logger.warn( + "Translating " + id + " to " + newid + ". In 1.20.3 entity parsing was reworked" + + ". You are advised to perform this rename in your config backs as this translation will be removed in the next major " + + "version of Terra."); + } + if(!id.startsWith("minecraft:")) throw new IllegalArgumentException("Invalid entity identifier " + id); + String entityID = id.toUpperCase(Locale.ROOT).substring(10); + + return new BukkitEntityType(switch(entityID) { + case "END_CRYSTAL" -> org.bukkit.entity.EntityType.END_CRYSTAL; + case "ENDER_CRYSTAL" -> throw new IllegalArgumentException( + "Invalid entity identifier " + id); // make sure this issue can't happen the other way around. + default -> org.bukkit.entity.EntityType.valueOf(entityID); + }); + } } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/PaperUtil.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/PaperUtil.java index 2cde19b1f5..c687fb0002 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/PaperUtil.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/PaperUtil.java @@ -19,6 +19,8 @@ import io.papermc.lib.PaperLib; +import java.util.concurrent.TimeUnit; + import com.dfsek.terra.bukkit.TerraBukkitPlugin; import static io.papermc.lib.PaperLib.suggestPaper; @@ -26,10 +28,10 @@ public final class PaperUtil { public static void checkPaper(TerraBukkitPlugin plugin) { - plugin.getFoliaLib().getImpl().runLaterAsync(() -> { + plugin.getAsyncScheduler().runDelayed(plugin, task -> { if(!PaperLib.isPaper()) { suggestPaper(plugin); } - }, 100L); + }, 100L, TimeUnit.SECONDS); } } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/VersionUtil.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/VersionUtil.java index 6bc06a4371..3f32b6be2b 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/VersionUtil.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/util/VersionUtil.java @@ -77,13 +77,13 @@ public boolean isSpigot() { public static final class MinecraftVersionInfo { private static final Logger logger = LoggerFactory.getLogger(MinecraftVersionInfo.class); - private static final Pattern VERSION_PATTERN = Pattern.compile("v?(\\d+)_(\\d+)_R(\\d+)"); + private static final Pattern VERSION_PATTERN = Pattern.compile("(\\d+)\\.(\\d+)(?:\\.(\\d+))?"); private final int major; private final int minor; private final int patch; private MinecraftVersionInfo() { - this(Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]); + this(Bukkit.getServer().getBukkitVersion().split("-")[0]); } private MinecraftVersionInfo(int major, int minor, int patch) { @@ -97,7 +97,7 @@ private MinecraftVersionInfo(String versionString) { if(versionMatcher.find()) { major = Integer.parseInt(versionMatcher.group(1)); minor = Integer.parseInt(versionMatcher.group(2)); - patch = Integer.parseInt(versionMatcher.group(3)); + patch = versionMatcher.group(3) != null ? Integer.parseInt(versionMatcher.group(3)) : -1; } else { logger.warn("Error while parsing minecraft version info. Continuing launch, but setting all versions to -1."); @@ -112,7 +112,11 @@ public String toString() { if(major == -1 && minor == -1 && patch == -1) return "Unknown"; - return String.format("v%d.%d.%d", major, minor, patch); + if(patch >= 0) { + return String.format("v%d.%d.%d", major, minor, patch); + } else { + return String.format("v%d.%d", major, minor); + } } public int getMajor() { diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java index f2d446de7f..4082658211 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitAdapter.java @@ -20,7 +20,6 @@ import org.bukkit.Location; import org.bukkit.Material; -import org.bukkit.TreeType; import org.bukkit.entity.Player; import org.bukkit.generator.WorldInfo; import org.bukkit.util.Vector; @@ -46,27 +45,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; import com.dfsek.terra.bukkit.world.inventory.BukkitItemStack; import com.dfsek.terra.bukkit.world.inventory.meta.BukkitEnchantment; -import com.dfsek.terra.transform.MapTransform; -import com.dfsek.terra.transform.TransformerImpl; /** * Utility class to adapt Bukkit enums to Terra enums. */ public final class BukkitAdapter { - public static TransformerImpl TREE_TRANSFORMER = new TransformerImpl.Builder() - .addTransform(new MapTransform() - .add(TreeType.COCOA_TREE, "JUNGLE_COCOA") - .add(TreeType.BIG_TREE, "LARGE_OAK") - .add(TreeType.TALL_REDWOOD, "LARGE_SPRUCE") - .add(TreeType.REDWOOD, "SPRUCE") - .add(TreeType.TREE, "OAK") - .add(TreeType.MEGA_REDWOOD, "MEGA_SPRUCE") - .add(TreeType.SWAMP, "SWAMP_OAK")) - .addTransform(TreeType::toString) - .build(); - - public static BlockState adapt(org.bukkit.block.data.BlockData data) { return BukkitBlockState.newInstance(data); } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitWorldProperties.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitWorldProperties.java index f9763df902..7ece9ac7b6 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitWorldProperties.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/BukkitWorldProperties.java @@ -1,9 +1,9 @@ package com.dfsek.terra.bukkit.world; -import org.bukkit.generator.WorldInfo; - import com.dfsek.terra.api.world.info.WorldProperties; +import org.bukkit.generator.WorldInfo; + public class BukkitWorldProperties implements WorldProperties { private final WorldInfo delegate; diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/block/state/BukkitMobSpawner.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/block/state/BukkitMobSpawner.java index 7bdc75d967..dc9d1ecb6c 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/block/state/BukkitMobSpawner.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/world/block/state/BukkitMobSpawner.java @@ -23,6 +23,7 @@ import com.dfsek.terra.api.block.entity.MobSpawner; import com.dfsek.terra.api.block.entity.SerialState; import com.dfsek.terra.api.entity.EntityType; +import com.dfsek.terra.bukkit.util.BukkitUtils; import com.dfsek.terra.bukkit.world.entity.BukkitEntityType; @@ -115,7 +116,7 @@ public void setSpawnRange(int spawnRange) { public void applyState(String state) { SerialState.parse(state).forEach((k, v) -> { switch(k) { - case "type" -> setSpawnedType(new BukkitEntityType(org.bukkit.entity.EntityType.valueOf(v.toUpperCase()))); + case "type" -> setSpawnedType(BukkitUtils.getEntityType(v)); case "delay" -> setDelay(Integer.parseInt(v)); case "min_delay" -> setMinSpawnDelay(Integer.parseInt(v)); case "max_delay" -> setMaxSpawnDelay(Integer.parseInt(v)); diff --git a/platforms/bukkit/common/src/main/resources/plugin.yml b/platforms/bukkit/common/src/main/resources/plugin.yml index d4bfd55340..782861cfea 100644 --- a/platforms/bukkit/common/src/main/resources/plugin.yml +++ b/platforms/bukkit/common/src/main/resources/plugin.yml @@ -2,8 +2,8 @@ name: "Terra" main: "com.dfsek.terra.bukkit.TerraBukkitPlugin" version: "@VERSION@" load: "STARTUP" -author: dfsek +authors: [ "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade" ] website: "@WIKI@" -api-version: "1.13" +api-version: "1.21.1" description: "@DESCRIPTION@" folia-supported: true diff --git a/platforms/bukkit/nms/v1_18_R2/build.gradle.kts b/platforms/bukkit/nms/v1_18_R2/build.gradle.kts deleted file mode 100644 index e3fc99195a..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -apply(plugin = "io.papermc.paperweight.userdev") - -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -dependencies { - api(project(":platforms:bukkit:common")) - paperDevBundle("1.18.2-R0.1-SNAPSHOT") - implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) -} - -tasks { - assemble { - dependsOn("reobfJar") - } -} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/AwfulBukkitHacks.java deleted file mode 100644 index bbfae8b2c6..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/AwfulBukkitHacks.java +++ /dev/null @@ -1,115 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; -import net.minecraft.core.Holder; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.NamespacedKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; -import com.dfsek.terra.registry.master.ConfigRegistry; - - -public class AwfulBukkitHacks { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.class); - private static final Map> terraBiomeMap = new HashMap<>(); - - - public static void registerBiomes(ConfigRegistry configRegistry) { - try { - LOGGER.info("Hacking biome registry..."); - WritableRegistry biomeRegistry = (WritableRegistry) Registries.biomeRegistry(); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, false); - - configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> { - try { - BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); - NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); - Biome platform = NMSBiomeInjector.createBiome( - biome, - biomeRegistry.get(vanillaMinecraftKey) // get - ); - - ResourceKey delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation("terra", - NMSBiomeInjector.createBiomeID( - pack, key))); - - BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform); - biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); - platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); - - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); - - LOGGER.debug("Registered biome: " + delegateKey); - } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } - })); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, true); // freeze registry again :) - - LOGGER.info("Doing tag garbage...."); - Map, List>> collect = biomeRegistry - .getTags() // streamKeysAndEntries - .collect(HashMap::new, - (map, pair) -> - map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), - HashMap::putAll); - - terraBiomeMap - .forEach((vb, terraBiomes) -> - NMSBiomeInjector.getEntry(biomeRegistry, vb) - .ifPresentOrElse( - vanilla -> terraBiomes - .forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb) - .ifPresentOrElse( - terra -> { - LOGGER.debug( - vanilla.unwrapKey() - .orElseThrow() - .location() + - " (vanilla for " + - terra.unwrapKey() - .orElseThrow() - .location() + - ": " + - vanilla.tags() - .toList()); - - vanilla.tags() - .forEach( - tag -> collect - .computeIfAbsent( - tag, - t -> new ArrayList<>()) - .add(terra)); - }, - () -> LOGGER.error( - "No such biome: {}", - tb))), - () -> LOGGER.error("No vanilla biome: {}", vb))); - - biomeRegistry.resetTags(); // clearTags - biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); // populateTags - - } catch(SecurityException | IllegalArgumentException exception) { - throw new RuntimeException(exception); - } - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInfo.java deleted file mode 100644 index 7e04ef1783..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import com.dfsek.terra.api.properties.Properties; - - -public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInjector.java deleted file mode 100644 index f56c32b5bb..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeInjector.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; - -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; - - -public class NMSBiomeInjector { - - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .map(registry::getOrCreateHolder); - } - - public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); // Builder - - - builder.biomeCategory(Reflection.BIOME.getBiomeCategory(vanilla)) - .precipitation(vanilla.getPrecipitation()) // getPrecipitation - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(vanilla.getGenerationSettings()) - .temperature(vanilla.getBaseTemperature()) - .downfall(vanilla.getDownfall()); - - - BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); - - effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier()); - - VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); - - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())); - - if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } else { - effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); - } - - if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); - } else { - effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); - } - - vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound); - vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound); - vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound); - vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic); - vanilla.getAmbientParticle().ifPresent(effects::ambientParticle); - - builder.specialEffects(effects.build()); - - return builder.build(); // build() - } - - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeProvider.java deleted file mode 100644 index 9fb99f13fb..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSBiomeProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import com.mojang.serialization.Codec; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate.Sampler; -import org.jetbrains.annotations.NotNull; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; - - -public class NMSBiomeProvider extends BiomeSource { - private final BiomeProvider delegate; - private final BiomeSource vanilla; - private final long seed; - private final Registry biomeRegistry = Registries.biomeRegistry(); - - public NMSBiomeProvider(BiomeProvider delegate, BiomeSource vanilla, long seed) { - super(delegate.stream() - .map(biome -> Registries.biomeRegistry() - .getOrCreateHolder(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()))); - this.delegate = delegate; - this.vanilla = vanilla; - this.seed = seed; - } - - @Override - protected Codec codec() { - return BiomeSource.CODEC; - } - - @Override - public @NotNull BiomeSource withSeed(long seed) { - return new NMSBiomeProvider(delegate, vanilla, seed); - } - - @Override - public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) { - return biomeRegistry.getOrCreateHolder(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed).getPlatformBiome()) - .getContext() - .get(NMSBiomeInfo.class) - .biomeKey()); - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java deleted file mode 100644 index 905867b62b..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSChunkGeneratorDelegate.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.SectionPos; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureFeatureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.biome.Climate; -import net.minecraft.world.level.biome.Climate.Sampler; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.structure.StructureSet; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement; -import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Collectors; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.util.MathUtil; -import com.dfsek.terra.api.util.generic.Lazy; -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSChunkGeneratorDelegate extends ChunkGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); - private static final Lazy> EMPTY = Lazy.lazy(List::of); - private final NMSBiomeProvider biomeSource; - private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; - private final ChunkGenerator vanilla; - private final ConfigPack pack; - private final long seed; - private final Map>> ringPositions = new Object2ObjectArrayMap<>(); - private volatile boolean rings = false; - - public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { - super(Registries.structureSet(), Optional.empty(), biomeProvider, biomeProvider, seed); - this.delegate = pack.getGeneratorProvider().newInstance(pack); - this.vanilla = vanilla; - this.biomeSource = biomeProvider; - this.pack = pack; - this.seed = seed; - } - - @Override - public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull BiomeManager biomeAccess, - @NotNull StructureFeatureManager structureAccessor, - @NotNull ChunkAccess chunk, GenerationStep.@NotNull Carving generationStep) { - // no-op - } - - @Override - public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk, - @NotNull StructureFeatureManager structureAccessor) { - vanilla.applyBiomeDecoration(world, chunk, structureAccessor); - } - - @Override - public int getSeaLevel() { - return vanilla.getSeaLevel(); - } - - @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull StructureFeatureManager structureAccessor, - @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, structureAccessor, chunk); - } - - @Override - public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureFeatureManager structures, @NotNull ChunkAccess chunk) { - // no-op - } - - @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; - } - - @Override - public @NotNull NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor height) { - /* - BlockState[] array = new BlockState[height.getHeight()]; - WorldProperties properties = new NMSWorldProperties(seed, height); - BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); - for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { - array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) - .getHandle()).getState(); - } - return new NoiseColumn(getMinY(), array); - */ - return vanilla.getBaseColumn(x, z, height); - } - - @Override // withSeed - public @NotNull ChunkGenerator withSeed(long seed) { - return new NMSChunkGeneratorDelegate(vanilla, pack, biomeSource, seed); - } - - @Override - public void spawnOriginalMobs(@NotNull WorldGenRegion regionlimitedworldaccess) { - vanilla.spawnOriginalMobs(regionlimitedworldaccess); - } - - @Override - public int getGenDepth() { - return vanilla.getGenDepth(); - } - - @Override - public @NotNull Sampler climateSampler() { - return Climate.empty(); - } - - @Override - public int getMinY() { - return vanilla.getMinY(); - } - - @Override - public int getBaseHeight(int x, int z, Heightmap.@NotNull Types heightmap, @NotNull LevelHeightAccessor world) { - WorldProperties properties = new NMSWorldProperties(seed, world); - int y = properties.getMaxHeight(); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - while(y >= getMinY() && !heightmap.isOpaque().test( - ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { - y--; - } - return y; - } - - @Nullable - @Override - public List getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement concentricringsstructureplacement) { - ensureStructuresGenerated(); - return ringPositions.getOrDefault(concentricringsstructureplacement, EMPTY).value(); - } - - @Override - public synchronized void ensureStructuresGenerated() { - if(!this.rings) { - super.ensureStructuresGenerated(); - this.populateStrongholdData(); - this.rings = true; - } - } - - private void populateStrongholdData() { - LOGGER.info("Generating safe stronghold data. This may take up to a minute."); - Set> set = this.runtimeBiomeSource.possibleBiomes(); - possibleStructureSets().map(Holder::value).forEach((holder) -> { // we dont need the spigot crap because it doesnt touch concentric. - StructurePlacement structureplacement = holder.placement(); - if(structureplacement instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) { - if(holder.structures().stream().anyMatch((structureset_a1) -> structureset_a1.generatesInMatchingBiome(set::contains))) { - this.ringPositions.put(concentricringsstructureplacement, - Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement))); - } - } - }); - } - - private List generateRingPositions(StructureSet holder, - ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot - if(concentricringsstructureplacement.count() == 0) { - return List.of(); - } - - List list = new ArrayList<>(); - Set> set = holder - .structures() - .stream() - .flatMap((structureset_a) -> structureset_a.structure().value().biomes().stream()) - .collect(Collectors.toSet()); - int i = concentricringsstructureplacement.distance(); - int j = concentricringsstructureplacement.count(); - int k = concentricringsstructureplacement.spread(); - Random random = new Random(); - - // Paper start - if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) == - net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) { - random.setSeed(this.conf.strongholdSeed); - } else { - // Paper end - random.setSeed(this.ringPlacementSeed); - } // Paper - double d0 = random.nextDouble() * 3.141592653589793D * 2.0D; - int l = 0; - int i1 = 0; - - for(int j1 = 0; j1 < j; ++j1) { - double d1 = (double) (4 * i + i * i1 * 6) + (random.nextDouble() - 0.5D) * (double) i * 2.5D; - int k1 = (int) Math.round(MathUtil.cos(d0) * d1); - int l1 = (int) Math.round(MathUtil.sin(d0) * d1); - int i2 = SectionPos.sectionToBlockCoord(k1, 8); - int j2 = SectionPos.sectionToBlockCoord(l1, 8); - - Objects.requireNonNull(set); - Pair> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, set::contains, random, - this.climateSampler()); - - if(pair != null) { - BlockPos blockposition = pair.getFirst(); - - k1 = SectionPos.blockToSectionCoord(blockposition.getX()); - l1 = SectionPos.blockToSectionCoord(blockposition.getZ()); - } - - list.add(new ChunkPos(k1, l1)); - d0 += 6.283185307179586D / (double) k; - ++l; - if(l == k) { - ++i1; - l = 0; - k += 2 * k / (i1 + 1); - k = Math.min(k, j - j1); - d0 += random.nextDouble() * 3.141592653589793D * 2.0D; - } - } - - return list; - } - - @Override - public void addDebugScreenInfo(@NotNull List arg0, @NotNull BlockPos arg1) { - - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInjectListener.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInjectListener.java deleted file mode 100644 index 9e055524a3..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInjectListener.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldInitEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; - - -public class NMSInjectListener implements Listener { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); - private static final Set INJECTED = new HashSet<>(); - private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); - - @EventHandler - public void onWorldInit(WorldInitEvent event) { - if(!INJECTED.contains(event.getWorld()) && - event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { - INJECT_LOCK.lock(); - INJECTED.add(event.getWorld()); - LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); - CraftWorld craftWorld = (CraftWorld) event.getWorld(); - ServerLevel serverWorld = craftWorld.getHandle(); - - ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); - - ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); - NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), vanilla.getBiomeSource(), craftWorld.getSeed()); - NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); - - custom.conf = vanilla.conf; // world config from Spigot - - serverWorld.getChunkSource().chunkMap.generator = custom; - - LOGGER.info("Successfully injected into world."); - - serverWorld.getChunkSource().chunkMap.generator.ensureStructuresGenerated(); // generate stronghold data now - - INJECT_LOCK.unlock(); - } - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSWorldProperties.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSWorldProperties.java deleted file mode 100644 index 875dc03307..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSWorldProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.world.level.LevelHeightAccessor; - -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSWorldProperties implements WorldProperties { - private final long seed; - private final LevelHeightAccessor height; - - public NMSWorldProperties(long seed, LevelHeightAccessor height) { - this.seed = seed; - this.height = height; - } - - @Override - public Object getHandle() { - return height; - } - - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return height.getMaxBuildHeight(); - } - - @Override - public int getMinHeight() { - return height.getMinBuildHeight(); - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Reflection.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Reflection.java deleted file mode 100644 index c6e3351a12..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Reflection.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.core.MappedRegistry; -import net.minecraft.world.level.biome.Biome; -import xyz.jpenilla.reflectionremapper.ReflectionRemapper; -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies; - - -public class Reflection { - public static final MappedRegistryProxy MAPPED_REGISTRY; - public static final BiomeProxy BIOME; - - static { - ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); - ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, - Reflection.class.getClassLoader()); - - MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); - BIOME = reflectionProxyFactory.reflectionProxy(BiomeProxy.class); - } - - - @Proxies(MappedRegistry.class) - public interface MappedRegistryProxy { - @FieldSetter("frozen") - void setFrozen(MappedRegistry instance, boolean frozen); - } - - - @Proxies(Biome.class) - public interface BiomeProxy { - @FieldGetter("biomeCategory") - Biome.BiomeCategory getBiomeCategory(Biome instance); - } -} diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Registries.java b/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Registries.java deleted file mode 100644 index 652d77cab3..0000000000 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/Registries.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.structure.StructureSet; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.CraftServer; - - -public class Registries { - private static Registry getRegistry(ResourceKey> key) { - CraftServer craftserver = (CraftServer) Bukkit.getServer(); - DedicatedServer dedicatedserver = craftserver.getServer(); - return dedicatedserver - .registryAccess() - .registryOrThrow( // getRegistry - key - ); - } - - public static Registry biomeRegistry() { - return getRegistry(Registry.BIOME_REGISTRY); - } - - public static Registry structureSet() { - return getRegistry(Registry.STRUCTURE_SET_REGISTRY); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/build.gradle.kts b/platforms/bukkit/nms/v1_19_R1/build.gradle.kts deleted file mode 100644 index 9b301aa706..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -apply(plugin = "io.papermc.paperweight.userdev") - -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -dependencies { - api(project(":platforms:bukkit:common")) - paperDevBundle("1.19-R0.1-SNAPSHOT") - implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) -} - -tasks { - assemble { - dependsOn("reobfJar") - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java deleted file mode 100644 index 92506d834d..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/AwfulBukkitHacks.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; -import net.minecraft.core.Holder; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.Registry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.data.BuiltinRegistries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.NamespacedKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; -import com.dfsek.terra.registry.master.ConfigRegistry; - - -public class AwfulBukkitHacks { - private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class); - - private static final Map> terraBiomeMap = new HashMap<>(); - - public static void registerBiomes(ConfigRegistry configRegistry) { - try { - LOGGER.info("Hacking biome registry..."); - WritableRegistry biomeRegistry = (WritableRegistry) Registries.biomeRegistry(); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, false); - - configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> { - try { - BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); - NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); - Biome platform = NMSBiomeInjector.createBiome( - biome, - Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)) // get - ); - - ResourceKey delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY, - new ResourceLocation("terra", - NMSBiomeInjector.createBiomeID(pack, key))); - - BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform); - biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); - platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); - - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); - - LOGGER.debug("Registered biome: " + delegateKey); - } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } - })); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, true); // freeze registry again :) - - LOGGER.info("Doing tag garbage...."); - Map, List>> collect = biomeRegistry - .getTags() // streamKeysAndEntries - .collect(HashMap::new, - (map, pair) -> - map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), - HashMap::putAll); - - terraBiomeMap - .forEach((vb, terraBiomes) -> - NMSBiomeInjector.getEntry(biomeRegistry, vb) - .ifPresentOrElse( - vanilla -> terraBiomes - .forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb) - .ifPresentOrElse( - terra -> { - LOGGER.debug( - vanilla.unwrapKey() - .orElseThrow() - .location() + - " (vanilla for " + - terra.unwrapKey() - .orElseThrow() - .location() + - ": " + - vanilla.tags() - .toList()); - - vanilla.tags() - .forEach( - tag -> collect - .computeIfAbsent( - tag, - t -> new ArrayList<>()) - .add(terra)); - }, - () -> LOGGER.error( - "No such biome: {}", - tb))), - () -> LOGGER.error("No vanilla biome: {}", vb))); - - biomeRegistry.resetTags(); - biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); - - } catch(SecurityException | IllegalArgumentException exception) { - throw new RuntimeException(exception); - } - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java deleted file mode 100644 index 02e67dc8d1..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import com.dfsek.terra.api.properties.Properties; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - - -public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java deleted file mode 100644 index 39a66e468e..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; - -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; - - -public class NMSBiomeInjector { - - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .map(registry::getOrCreateHolderOrThrow); - } - - public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); - - builder - .precipitation(vanilla.getPrecipitation()) - .downfall(vanilla.getDownfall()) - .temperature(vanilla.getBaseTemperature()) - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(vanilla.getGenerationSettings()); - - - BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); - - effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier()); - - VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); - - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())); - - if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } else { - effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); - } - - if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); - } else { - // grass - effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); - } - - vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound); - vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound); - vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound); - vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic); - vanilla.getAmbientParticle().ifPresent(effects::ambientParticle); - - builder.specialEffects(effects.build()); - - return builder.build(); - } - - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java deleted file mode 100644 index ee7a054434..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import com.mojang.serialization.Codec; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate.Sampler; -import org.jetbrains.annotations.NotNull; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; - - -public class NMSBiomeProvider extends BiomeSource { - private final BiomeProvider delegate; - private final long seed; - private final Registry biomeRegistry = Registries.biomeRegistry(); - - public NMSBiomeProvider(BiomeProvider delegate, long seed) { - super(delegate.stream() - .map(biome -> Registries.biomeRegistry() - .getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()))); - this.delegate = delegate; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return BiomeSource.CODEC; - } - - @Override - public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) { - return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed) - .getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java deleted file mode 100644 index 6e374ff8b4..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.SectionPos; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.util.RandomSource; -import net.minecraft.world.level.ChunkPos; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Beardifier; -import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext; -import net.minecraft.world.level.levelgen.GenerationStep.Carving; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.structure.Structure; -import net.minecraft.world.level.levelgen.structure.StructureSet; -import net.minecraft.world.level.levelgen.structure.StructureSet.StructureSelectionEntry; -import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; -import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import java.util.stream.Stream; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.util.MathUtil; -import com.dfsek.terra.api.util.generic.Lazy; -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.info.WorldProperties; -import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions; -import com.dfsek.terra.bukkit.world.BukkitWorldProperties; -import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; - - -public class NMSChunkGeneratorDelegate extends ChunkGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); - private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; - - private final ChunkGenerator vanilla; - private final ConfigPack pack; - - private final long seed; - private final Map>> ringPositions = new Object2ObjectArrayMap<>(); - private volatile boolean rings = false; - - public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { - super(Registries.structureSet(), Optional.empty(), biomeProvider); - this.delegate = pack.getGeneratorProvider().newInstance(pack); - this.vanilla = vanilla; - this.pack = pack; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; - } - - @Override - public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) { - // no-op - } - - @Override - public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig, - @NotNull ChunkAccess chunk) { - // no-op - } - - @Override - public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk, - @NotNull StructureManager structureAccessor) { - vanilla.applyBiomeDecoration(world, chunk, structureAccessor); - } - - @Override - public void spawnOriginalMobs(@NotNull WorldGenRegion region) { - vanilla.spawnOriginalMobs(region); - } - - @Override - public int getGenDepth() { - return vanilla.getGenDepth(); - } - - @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull RandomState noiseConfig, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk) - .thenApply(c -> { - LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); - if(compatibilityOptions.isBeard()) { - beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), - biomeProvider, compatibilityOptions); - } - return c; - }); - } - - private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider, - PreLoadCompatibilityOptions compatibilityOptions) { - Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos()); - double threshold = compatibilityOptions.getBeardThreshold(); - double airThreshold = compatibilityOptions.getAirThreshold(); - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int depth = 0; - for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) { - double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi)); - if(noise > threshold) { - chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate - .getPalette(x + xi, y, z + zi, world, biomeProvider) - .get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false); - depth++; - } else if(noise < airThreshold) { - chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false); - } else { - depth = 0; - } - } - } - } - } - - @Override - public int getSeaLevel() { - return vanilla.getSeaLevel(); - } - - @Override - public int getMinY() { - return vanilla.getMinY(); - } - - @Override - public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - WorldProperties properties = new NMSWorldProperties(seed, world); - int y = properties.getMaxHeight(); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - while(y >= getMinY() && !heightmap.isOpaque().test( - ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { - y--; - } - return y; - } - - @Override - public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - /* - BlockState[] array = new BlockState[world.getHeight()]; - WorldProperties properties = new NMSWorldProperties(seed, world); - BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); - for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { - array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) - .getHandle()).getState(); - } - return new NoiseColumn(getMinY(), array); - - */ - return vanilla.getBaseColumn(x, z, world, noiseConfig); - } - - @Override - public void addDebugScreenInfo(@NotNull List text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) { - - } - - @Override - public void ensureStructuresGenerated(@NotNull RandomState noiseConfig) { - if(!this.rings) { - super.ensureStructuresGenerated(noiseConfig); - this.populateStrongholdData(noiseConfig); - this.rings = true; - } - - } - - @Override - public List getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement structurePlacement, - @NotNull RandomState noiseConfig) { - ensureStructuresGenerated(noiseConfig); - return ringPositions.get(structurePlacement).value(); - } - - private void populateStrongholdData(RandomState noiseConfig) { - LOGGER.info("Generating safe stronghold data. This may take up to a minute."); - Set> set = this.biomeSource.possibleBiomes(); - possibleStructureSets().map(Holder::value).forEach((holder) -> { - boolean match = false; - for(StructureSelectionEntry structureset_a : holder.structures()) { - Structure structure = structureset_a.structure().value(); - Stream> stream = structure.biomes().stream(); - if(stream.anyMatch(set::contains)) { - match = true; - } - } - - if(match) { - if(holder.placement() instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) { - this.ringPositions.put(concentricringsstructureplacement, Lazy.lazy( - () -> this.generateRingPositions(holder, noiseConfig, concentricringsstructureplacement))); - } - } - }); - } - - private List generateRingPositions(StructureSet holder, RandomState randomstate, - ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot - if(concentricringsstructureplacement.count() == 0) { - return List.of(); - } - - List list = new ArrayList<>(); - int i = concentricringsstructureplacement.distance(); - int j = concentricringsstructureplacement.count(); - int k = concentricringsstructureplacement.spread(); - HolderSet holderset = concentricringsstructureplacement.preferredBiomes(); - RandomSource randomsource = RandomSource.create(); - - if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) == - net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) { - randomsource.setSeed(this.conf.strongholdSeed); - } else { - randomsource.setSeed(randomstate.legacyLevelSeed()); - } - double d0 = randomsource.nextDouble() * 3.141592653589793D * 2.0D; - int l = 0; - int i1 = 0; - - for(int j1 = 0; j1 < j; ++j1) { - double d1 = (double) (4 * i + i * i1 * 6) + (randomsource.nextDouble() - 0.5D) * (double) i * 2.5D; - int k1 = (int) Math.round(MathUtil.cos(d0) * d1); - int l1 = (int) Math.round(MathUtil.sin(d0) * d1); - int i2 = SectionPos.sectionToBlockCoord(k1, 8); - int j2 = SectionPos.sectionToBlockCoord(l1, 8); - - Objects.requireNonNull(holderset); - Pair> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, holderset::contains, randomsource, - randomstate.sampler()); - - if(pair != null) { - BlockPos blockposition = pair.getFirst(); - - k1 = SectionPos.blockToSectionCoord(blockposition.getX()); - l1 = SectionPos.blockToSectionCoord(blockposition.getZ()); - } - - list.add(new ChunkPos(k1, l1)); - d0 += 6.283185307179586D / (double) k; - ++l; - if(l == k) { - ++i1; - l = 0; - k += 2 * k / (i1 + 1); - k = Math.min(k, j - j1); - d0 += randomsource.nextDouble() * 3.141592653589793D * 2.0D; - } - } - - return list; - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java deleted file mode 100644 index 82a293cd19..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import org.bukkit.Bukkit; - -import com.dfsek.terra.bukkit.PlatformImpl; -import com.dfsek.terra.bukkit.nms.Initializer; - - -public class NMSInitializer implements Initializer { - @Override - public void initialize(PlatformImpl platform) { - AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry()); - Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java deleted file mode 100644 index 0f11f700d2..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldInitEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; - - -public class NMSInjectListener implements Listener { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); - private static final Set INJECTED = new HashSet<>(); - private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); - - @EventHandler - public void onWorldInit(WorldInitEvent event) { - if(!INJECTED.contains(event.getWorld()) && - event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { - INJECT_LOCK.lock(); - INJECTED.add(event.getWorld()); - LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); - CraftWorld craftWorld = (CraftWorld) event.getWorld(); - ServerLevel serverWorld = craftWorld.getHandle(); - - ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); - - ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); - NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed()); - NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); - - custom.conf = vanilla.conf; // world config from Spigot - - serverWorld.getChunkSource().chunkMap.generator = custom; - - LOGGER.info("Successfully injected into world."); - - INJECT_LOCK.unlock(); - } - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java deleted file mode 100644 index 9348ca0478..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import net.minecraft.world.level.LevelHeightAccessor; - -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSWorldProperties implements WorldProperties { - private final long seed; - private final LevelHeightAccessor height; - - public NMSWorldProperties(long seed, LevelHeightAccessor height) { - this.seed = seed; - this.height = height; - } - - @Override - public Object getHandle() { - return height; - } - - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return height.getMaxBuildHeight(); - } - - @Override - public int getMinHeight() { - return height.getMinBuildHeight(); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Reflection.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Reflection.java deleted file mode 100644 index 84263a6677..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Reflection.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import net.minecraft.core.MappedRegistry; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.StructureManager; -import xyz.jpenilla.reflectionremapper.ReflectionRemapper; -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies; - - -public class Reflection { - public static final MappedRegistryProxy MAPPED_REGISTRY; - public static final StructureManagerProxy STRUCTURE_MANAGER; - - static { - ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); - ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, - Reflection.class.getClassLoader()); - - MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); - STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class); - } - - - @Proxies(MappedRegistry.class) - public interface MappedRegistryProxy { - @FieldSetter("frozen") - void setFrozen(MappedRegistry instance, boolean frozen); - } - - - @Proxies(StructureManager.class) - public interface StructureManagerProxy { - @FieldGetter("level") - LevelAccessor getLevel(StructureManager instance); - } -} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java deleted file mode 100644 index 1ff9641062..0000000000 --- a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R1; - -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.levelgen.structure.StructureSet; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R1.CraftServer; - - -public class Registries { - private static Registry getRegistry(ResourceKey> key) { - CraftServer craftserver = (CraftServer) Bukkit.getServer(); - DedicatedServer dedicatedserver = craftserver.getServer(); - return dedicatedserver - .registryAccess() - .registryOrThrow( // getRegistry - key - ); - } - - public static Registry biomeRegistry() { - return getRegistry(Registry.BIOME_REGISTRY); - } - - public static Registry structureSet() { - return getRegistry(Registry.STRUCTURE_SET_REGISTRY); - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/build.gradle.kts b/platforms/bukkit/nms/v1_19_R2/build.gradle.kts deleted file mode 100644 index c6f6d82059..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -apply(plugin = "io.papermc.paperweight.userdev") - -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -dependencies { - api(project(":platforms:bukkit:common")) - paperDevBundle("1.19.3-R0.1-SNAPSHOT") - implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) -} - -tasks { - assemble { - dependsOn("reobfJar") - } -} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java deleted file mode 100644 index 725f2fb1a1..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/AwfulBukkitHacks.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.NamespacedKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; -import com.dfsek.terra.registry.master.ConfigRegistry; - - -public class AwfulBukkitHacks { - private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class); - - private static final Map> terraBiomeMap = new HashMap<>(); - - public static void registerBiomes(ConfigRegistry configRegistry) { - try { - LOGGER.info("Hacking biome registry..."); - WritableRegistry biomeRegistry = (WritableRegistry) RegistryFetcher.biomeRegistry(); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, false); - - configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> { - try { - BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); - NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); - Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey))); - - ResourceKey delegateKey = ResourceKey.create( - Registries.BIOME, - new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key)) - ); - - Reference holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); - Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder. - - platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); - - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); - - LOGGER.debug("Registered biome: " + delegateKey); - } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } - })); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, true); // freeze registry again :) - - LOGGER.info("Doing tag garbage...."); - Map, List>> collect = biomeRegistry - .getTags() // streamKeysAndEntries - .collect(HashMap::new, - (map, pair) -> - map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), - HashMap::putAll); - - terraBiomeMap - .forEach((vb, terraBiomes) -> - NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse( - vanilla -> terraBiomes.forEach( - tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse( - terra -> { - LOGGER.debug("{} (vanilla for {}): {}", - vanilla.unwrapKey().orElseThrow().location(), - terra.unwrapKey().orElseThrow().location(), - vanilla.tags().toList()); - vanilla.tags() - .forEach(tag -> collect - .computeIfAbsent(tag, t -> new ArrayList<>()) - .add(terra)); - }, - () -> LOGGER.error("No such biome: {}", tb))), - () -> LOGGER.error("No vanilla biome: {}", vb))); - - biomeRegistry.resetTags(); - biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); - - } catch(SecurityException | IllegalArgumentException exception) { - throw new RuntimeException(exception); - } - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java deleted file mode 100644 index 0b8c36a502..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInjector.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; - -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; - - -public class NMSBiomeInjector { - - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .flatMap(registry::getHolder); - } - - public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); - - builder - .precipitation(vanilla.getPrecipitation()) - .downfall(vanilla.getDownfall()) - .temperature(vanilla.getBaseTemperature()) - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(vanilla.getGenerationSettings()); - - - BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); - - effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier()); - - VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); - - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())); - - if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } else { - effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); - } - - if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); - } else { - // grass - effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); - } - - vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound); - vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound); - vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound); - vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic); - vanilla.getAmbientParticle().ifPresent(effects::ambientParticle); - - builder.specialEffects(effects.build()); - - return builder.build(); - } - - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java deleted file mode 100644 index 4e4b9f1c5d..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import com.mojang.serialization.Codec; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate.Sampler; -import org.jetbrains.annotations.NotNull; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; - - -public class NMSBiomeProvider extends BiomeSource { - private final BiomeProvider delegate; - private final long seed; - private final Registry biomeRegistry = RegistryFetcher.biomeRegistry(); - - public NMSBiomeProvider(BiomeProvider delegate, long seed) { - super(delegate.stream() - .map(biome -> RegistryFetcher.biomeRegistry() - .getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()))); - this.delegate = delegate; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return BiomeSource.CODEC; - } - - @Override - public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) { - return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed) - .getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java deleted file mode 100644 index 9059326cae..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSChunkGeneratorDelegate.java +++ /dev/null @@ -1,174 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import com.mojang.serialization.Codec; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Beardifier; -import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext; -import net.minecraft.world.level.levelgen.GenerationStep.Carving; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.info.WorldProperties; -import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions; -import com.dfsek.terra.bukkit.world.BukkitWorldProperties; -import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; - - -public class NMSChunkGeneratorDelegate extends ChunkGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); - private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; - - private final ChunkGenerator vanilla; - private final ConfigPack pack; - - private final long seed; - - public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { - super(biomeProvider); - this.delegate = pack.getGeneratorProvider().newInstance(pack); - this.vanilla = vanilla; - this.pack = pack; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; - } - - @Override - public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) { - // no-op - } - - @Override - public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig, - @NotNull ChunkAccess chunk) { - // no-op - } - - @Override - public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk, - @NotNull StructureManager structureAccessor) { - vanilla.applyBiomeDecoration(world, chunk, structureAccessor); - } - - @Override - public void spawnOriginalMobs(@NotNull WorldGenRegion region) { - vanilla.spawnOriginalMobs(region); - } - - @Override - public int getGenDepth() { - return vanilla.getGenDepth(); - } - - @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull RandomState noiseConfig, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk) - .thenApply(c -> { - LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); - if(compatibilityOptions.isBeard()) { - beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), - biomeProvider, compatibilityOptions); - } - return c; - }); - } - - private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider, - PreLoadCompatibilityOptions compatibilityOptions) { - Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos()); - double threshold = compatibilityOptions.getBeardThreshold(); - double airThreshold = compatibilityOptions.getAirThreshold(); - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int depth = 0; - for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) { - double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi)); - if(noise > threshold) { - chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate - .getPalette(x + xi, y, z + zi, world, biomeProvider) - .get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false); - depth++; - } else if(noise < airThreshold) { - chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false); - } else { - depth = 0; - } - } - } - } - } - - @Override - public int getSeaLevel() { - return vanilla.getSeaLevel(); - } - - @Override - public int getMinY() { - return vanilla.getMinY(); - } - - @Override - public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - WorldProperties properties = new NMSWorldProperties(seed, world); - int y = properties.getMaxHeight(); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - while(y >= getMinY() && !heightmap.isOpaque().test( - ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { - y--; - } - return y; - } - - @Override - public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - /* - BlockState[] array = new BlockState[world.getHeight()]; - WorldProperties properties = new NMSWorldProperties(seed, world); - BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); - for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { - array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) - .getHandle()).getState(); - } - return new NoiseColumn(getMinY(), array); - - */ - return vanilla.getBaseColumn(x, z, world, noiseConfig); - } - - @Override - public void addDebugScreenInfo(@NotNull List text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) { - - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java deleted file mode 100644 index 05814cfd4d..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import org.bukkit.Bukkit; - -import com.dfsek.terra.bukkit.PlatformImpl; -import com.dfsek.terra.bukkit.nms.Initializer; - - -public class NMSInitializer implements Initializer { - @Override - public void initialize(PlatformImpl platform) { - AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry()); - Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java deleted file mode 100644 index 6ce184da05..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSInjectListener.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldInitEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; - - -public class NMSInjectListener implements Listener { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); - private static final Set INJECTED = new HashSet<>(); - private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); - - @EventHandler - public void onWorldInit(WorldInitEvent event) { - if(!INJECTED.contains(event.getWorld()) && - event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { - INJECT_LOCK.lock(); - INJECTED.add(event.getWorld()); - LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); - CraftWorld craftWorld = (CraftWorld) event.getWorld(); - ServerLevel serverWorld = craftWorld.getHandle(); - - ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); - - ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); - NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed()); - - serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); - - LOGGER.info("Successfully injected into world."); - - INJECT_LOCK.unlock(); - } - } -} diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java b/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java deleted file mode 100644 index ed353eafc1..0000000000 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/RegistryFetcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; - -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R2.CraftServer; - - -public class RegistryFetcher { - private static Registry getRegistry(ResourceKey> key) { - CraftServer craftserver = (CraftServer) Bukkit.getServer(); - DedicatedServer dedicatedserver = craftserver.getServer(); - return dedicatedserver - .registryAccess() - .registryOrThrow(key); - } - - public static Registry biomeRegistry() { - return getRegistry(Registries.BIOME); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/build.gradle.kts b/platforms/bukkit/nms/v1_19_R3/build.gradle.kts deleted file mode 100644 index 4b2ad7d637..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -apply(plugin = "io.papermc.paperweight.userdev") - -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -dependencies { - api(project(":platforms:bukkit:common")) - paperDevBundle("1.19.4-R0.1-SNAPSHOT") - implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) -} - -tasks { - assemble { - dependsOn("reobfJar") - } -} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/AwfulBukkitHacks.java deleted file mode 100644 index b2ac9d28b2..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/AwfulBukkitHacks.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.NamespacedKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; -import com.dfsek.terra.registry.master.ConfigRegistry; - - -public class AwfulBukkitHacks { - private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class); - - private static final Map> terraBiomeMap = new HashMap<>(); - - public static void registerBiomes(ConfigRegistry configRegistry) { - try { - LOGGER.info("Hacking biome registry..."); - WritableRegistry biomeRegistry = (WritableRegistry) RegistryFetcher.biomeRegistry(); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, false); - - configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> { - try { - BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); - NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); - Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey))); - - ResourceKey delegateKey = ResourceKey.create( - Registries.BIOME, - new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key)) - ); - - Reference holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); - Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder. - - platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); - - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); - - LOGGER.debug("Registered biome: " + delegateKey); - } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } - })); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, true); // freeze registry again :) - - LOGGER.info("Doing tag garbage...."); - Map, List>> collect = biomeRegistry - .getTags() // streamKeysAndEntries - .collect(HashMap::new, - (map, pair) -> - map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), - HashMap::putAll); - - terraBiomeMap - .forEach((vb, terraBiomes) -> - NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse( - vanilla -> terraBiomes.forEach( - tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse( - terra -> { - LOGGER.debug("{} (vanilla for {}): {}", - vanilla.unwrapKey().orElseThrow().location(), - terra.unwrapKey().orElseThrow().location(), - vanilla.tags().toList()); - vanilla.tags() - .forEach(tag -> collect - .computeIfAbsent(tag, t -> new ArrayList<>()) - .add(terra)); - }, - () -> LOGGER.error("No such biome: {}", tb))), - () -> LOGGER.error("No vanilla biome: {}", vb))); - - biomeRegistry.resetTags(); - biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); - - } catch(SecurityException | IllegalArgumentException exception) { - throw new RuntimeException(exception); - } - } -} - diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInfo.java deleted file mode 100644 index 816d96068d..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import com.dfsek.terra.api.properties.Properties; - - -public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInjector.java deleted file mode 100644 index 733fd38f4f..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeInjector.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; - -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; - - -public class NMSBiomeInjector { - - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .flatMap(registry::getHolder); - } - - public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); - - builder - .downfall(vanilla.climateSettings.downfall()) - .temperature(vanilla.getBaseTemperature()) - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(vanilla.getGenerationSettings()); - - - BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); - - effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier()); - - VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); - - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())); - - if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } else { - effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); - } - - if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); - } else { - // grass - effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); - } - - vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound); - vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound); - vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound); - vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic); - vanilla.getAmbientParticle().ifPresent(effects::ambientParticle); - - builder.specialEffects(effects.build()); - - return builder.build(); - } - - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeProvider.java deleted file mode 100644 index ed5ea15893..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSBiomeProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import com.mojang.serialization.Codec; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate.Sampler; -import org.jetbrains.annotations.NotNull; - -import java.util.stream.Stream; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; - - -public class NMSBiomeProvider extends BiomeSource { - private final BiomeProvider delegate; - private final long seed; - private final Registry biomeRegistry = RegistryFetcher.biomeRegistry(); - - public NMSBiomeProvider(BiomeProvider delegate, long seed) { - super(); - this.delegate = delegate; - this.seed = seed; - } - - @Override - protected Stream> collectPossibleBiomes() { - return delegate.stream() - .map(biome -> RegistryFetcher.biomeRegistry() - .getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey())); - } - - @Override - protected @NotNull Codec codec() { - return BiomeSource.CODEC; - } - - @Override - public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) { - return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed) - .getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSChunkGeneratorDelegate.java deleted file mode 100644 index c697bd0c19..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSChunkGeneratorDelegate.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import com.mojang.serialization.Codec; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Beardifier; -import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext; -import net.minecraft.world.level.levelgen.GenerationStep.Carving; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.info.WorldProperties; -import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions; -import com.dfsek.terra.bukkit.world.BukkitWorldProperties; -import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; - - -public class NMSChunkGeneratorDelegate extends ChunkGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); - private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; - - private final ChunkGenerator vanilla; - private final ConfigPack pack; - - private final long seed; - - public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { - super(biomeProvider); - this.delegate = pack.getGeneratorProvider().newInstance(pack); - this.vanilla = vanilla; - this.pack = pack; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; - } - - @Override - public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) { - // no-op - } - - @Override - public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig, - @NotNull ChunkAccess chunk) { - // no-op - } - - @Override - public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk, - @NotNull StructureManager structureAccessor) { - vanilla.applyBiomeDecoration(world, chunk, structureAccessor); - } - - @Override - public void spawnOriginalMobs(@NotNull WorldGenRegion region) { - vanilla.spawnOriginalMobs(region); - } - - @Override - public int getGenDepth() { - return vanilla.getGenDepth(); - } - - @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull RandomState noiseConfig, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk) - .thenApply(c -> { - LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); - if(compatibilityOptions.isBeard()) { - beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), - biomeProvider, compatibilityOptions); - } - return c; - }); - } - - private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider, - PreLoadCompatibilityOptions compatibilityOptions) { - Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos()); - double threshold = compatibilityOptions.getBeardThreshold(); - double airThreshold = compatibilityOptions.getAirThreshold(); - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int depth = 0; - for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) { - double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi)); - if(noise > threshold) { - chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate - .getPalette(x + xi, y, z + zi, world, biomeProvider) - .get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false); - depth++; - } else if(noise < airThreshold) { - chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false); - } else { - depth = 0; - } - } - } - } - } - - @Override - public int getSeaLevel() { - return vanilla.getSeaLevel(); - } - - @Override - public int getMinY() { - return vanilla.getMinY(); - } - - @Override - public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - WorldProperties properties = new NMSWorldProperties(seed, world); - int y = properties.getMaxHeight(); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - while(y >= getMinY() && !heightmap.isOpaque().test( - ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { - y--; - } - return y; - } - - @Override - public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - BlockState[] array = new BlockState[world.getHeight()]; - WorldProperties properties = new NMSWorldProperties(seed, world); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { - array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) - .getHandle()).getState(); - } - return new NoiseColumn(getMinY(), array); - } - - @Override - public void addDebugScreenInfo(@NotNull List text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) { - - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInitializer.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInitializer.java deleted file mode 100644 index 99797e8ab3..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import org.bukkit.Bukkit; - -import com.dfsek.terra.bukkit.PlatformImpl; -import com.dfsek.terra.bukkit.nms.Initializer; - - -public class NMSInitializer implements Initializer { - @Override - public void initialize(PlatformImpl platform) { - AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry()); - Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSWorldProperties.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSWorldProperties.java deleted file mode 100644 index 2cda90452f..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSWorldProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import net.minecraft.world.level.LevelHeightAccessor; - -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSWorldProperties implements WorldProperties { - private final long seed; - private final LevelHeightAccessor height; - - public NMSWorldProperties(long seed, LevelHeightAccessor height) { - this.seed = seed; - this.height = height; - } - - @Override - public Object getHandle() { - return height; - } - - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return height.getMaxBuildHeight(); - } - - @Override - public int getMinHeight() { - return height.getMinBuildHeight(); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/Reflection.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/Reflection.java deleted file mode 100644 index 43d362ee66..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/Reflection.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.StructureManager; -import xyz.jpenilla.reflectionremapper.ReflectionRemapper; -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName; -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies; - - -public class Reflection { - public static final MappedRegistryProxy MAPPED_REGISTRY; - public static final StructureManagerProxy STRUCTURE_MANAGER; - - public static final ReferenceProxy REFERENCE; - - static { - ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); - ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, - Reflection.class.getClassLoader()); - - MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); - STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class); - REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class); - } - - - @Proxies(MappedRegistry.class) - public interface MappedRegistryProxy { - @FieldSetter("frozen") - void setFrozen(MappedRegistry instance, boolean frozen); - } - - - @Proxies(StructureManager.class) - public interface StructureManagerProxy { - @FieldGetter("level") - LevelAccessor getLevel(StructureManager instance); - } - - - @Proxies(Holder.Reference.class) - public interface ReferenceProxy { - @MethodName("bindValue") - void invokeBindValue(Reference instance, T value); - } -} diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/RegistryFetcher.java b/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/RegistryFetcher.java deleted file mode 100644 index e033491bba..0000000000 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/RegistryFetcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; - -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; - - -public class RegistryFetcher { - private static Registry getRegistry(ResourceKey> key) { - CraftServer craftserver = (CraftServer) Bukkit.getServer(); - DedicatedServer dedicatedserver = craftserver.getServer(); - return dedicatedserver - .registryAccess() - .registryOrThrow(key); - } - - public static Registry biomeRegistry() { - return getRegistry(Registries.BIOME); - } -} diff --git a/platforms/bukkit/nms/v1_20_R1/build.gradle.kts b/platforms/bukkit/nms/v1_20_R1/build.gradle.kts deleted file mode 100644 index c3c0d9809b..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/build.gradle.kts +++ /dev/null @@ -1,17 +0,0 @@ -apply(plugin = "io.papermc.paperweight.userdev") - -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - -dependencies { - api(project(":platforms:bukkit:common")) - paperDevBundle("1.20.1-R0.1-SNAPSHOT") - implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper) -} - -tasks { - assemble { - dependsOn("reobfJar") - } -} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/AwfulBukkitHacks.java deleted file mode 100644 index 7994a0074d..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/AwfulBukkitHacks.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.core.WritableRegistry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.NamespacedKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; -import com.dfsek.terra.registry.master.ConfigRegistry; - - -public class AwfulBukkitHacks { - private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class); - - private static final Map> terraBiomeMap = new HashMap<>(); - - public static void registerBiomes(ConfigRegistry configRegistry) { - try { - LOGGER.info("Hacking biome registry..."); - WritableRegistry biomeRegistry = (WritableRegistry) RegistryFetcher.biomeRegistry(); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, false); - - configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> { - try { - BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); - NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); - Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey))); - - ResourceKey delegateKey = ResourceKey.create( - Registries.BIOME, - new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key)) - ); - - Reference holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); - Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder. - - platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); - - terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location()); - - LOGGER.debug("Registered biome: " + delegateKey); - } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(e); - } - })); - - Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry) biomeRegistry, true); // freeze registry again :) - - LOGGER.info("Doing tag garbage...."); - Map, List>> collect = biomeRegistry - .getTags() // streamKeysAndEntries - .collect(HashMap::new, - (map, pair) -> - map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())), - HashMap::putAll); - - terraBiomeMap - .forEach((vb, terraBiomes) -> - NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse( - vanilla -> terraBiomes.forEach( - tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse( - terra -> { - LOGGER.debug("{} (vanilla for {}): {}", - vanilla.unwrapKey().orElseThrow().location(), - terra.unwrapKey().orElseThrow().location(), - vanilla.tags().toList()); - vanilla.tags() - .forEach(tag -> collect - .computeIfAbsent(tag, t -> new ArrayList<>()) - .add(terra)); - }, - () -> LOGGER.error("No such biome: {}", tb))), - () -> LOGGER.error("No vanilla biome: {}", vb))); - - biomeRegistry.resetTags(); - biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); - - } catch(SecurityException | IllegalArgumentException exception) { - throw new RuntimeException(exception); - } - } -} - diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInfo.java deleted file mode 100644 index 7d8203ce31..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import com.dfsek.terra.api.properties.Properties; - - -public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { -} diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeProvider.java deleted file mode 100644 index 48f0483180..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import com.mojang.serialization.Codec; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate.Sampler; -import org.jetbrains.annotations.NotNull; - -import java.util.stream.Stream; - -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; - - -public class NMSBiomeProvider extends BiomeSource { - private final BiomeProvider delegate; - private final long seed; - private final Registry biomeRegistry = RegistryFetcher.biomeRegistry(); - - public NMSBiomeProvider(BiomeProvider delegate, long seed) { - super(); - this.delegate = delegate; - this.seed = seed; - } - - @Override - protected Stream> collectPossibleBiomes() { - return delegate.stream() - .map(biome -> RegistryFetcher.biomeRegistry() - .getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey())); - } - - @Override - protected @NotNull Codec codec() { - return BiomeSource.CODEC; - } - - @Override - public @NotNull Holder getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) { - return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed) - .getPlatformBiome()).getContext() - .get(NMSBiomeInfo.class) - .biomeKey()); - } -} diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInitializer.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInitializer.java deleted file mode 100644 index 6fb689ee78..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import org.bukkit.Bukkit; - -import com.dfsek.terra.bukkit.PlatformImpl; -import com.dfsek.terra.bukkit.nms.Initializer; - - -public class NMSInitializer implements Initializer { - @Override - public void initialize(PlatformImpl platform) { - AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry()); - Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); - } -} diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInjectListener.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInjectListener.java deleted file mode 100644 index 3f7c9e060b..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSInjectListener.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R1.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldInitEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; - - -public class NMSInjectListener implements Listener { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); - private static final Set INJECTED = new HashSet<>(); - private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); - - @EventHandler - public void onWorldInit(WorldInitEvent event) { - if(!INJECTED.contains(event.getWorld()) && - event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { - INJECT_LOCK.lock(); - INJECTED.add(event.getWorld()); - LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); - CraftWorld craftWorld = (CraftWorld) event.getWorld(); - ServerLevel serverWorld = craftWorld.getHandle(); - - ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); - - ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); - NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed()); - - serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); - - LOGGER.info("Successfully injected into world."); - - INJECT_LOCK.unlock(); - } - } -} diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSWorldProperties.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSWorldProperties.java deleted file mode 100644 index 48effeb5fc..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSWorldProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import net.minecraft.world.level.LevelHeightAccessor; - -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSWorldProperties implements WorldProperties { - private final long seed; - private final LevelHeightAccessor height; - - public NMSWorldProperties(long seed, LevelHeightAccessor height) { - this.seed = seed; - this.height = height; - } - - @Override - public Object getHandle() { - return height; - } - - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return height.getMaxBuildHeight(); - } - - @Override - public int getMinHeight() { - return height.getMinBuildHeight(); - } -} diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/Reflection.java b/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/Reflection.java deleted file mode 100644 index a11dd1b15c..0000000000 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/Reflection.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; - -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.StructureManager; -import xyz.jpenilla.reflectionremapper.ReflectionRemapper; -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName; -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies; - - -public class Reflection { - public static final MappedRegistryProxy MAPPED_REGISTRY; - public static final StructureManagerProxy STRUCTURE_MANAGER; - - public static final ReferenceProxy REFERENCE; - - static { - ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); - ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, - Reflection.class.getClassLoader()); - - MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); - STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class); - REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class); - } - - - @Proxies(MappedRegistry.class) - public interface MappedRegistryProxy { - @FieldSetter("frozen") - void setFrozen(MappedRegistry instance, boolean frozen); - } - - - @Proxies(StructureManager.class) - public interface StructureManagerProxy { - @FieldGetter("level") - LevelAccessor getLevel(StructureManager instance); - } - - - @Proxies(Holder.Reference.class) - public interface ReferenceProxy { - @MethodName("bindValue") - void invokeBindValue(Reference instance, T value); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInfo.java deleted file mode 100644 index fd415fb208..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInfo.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.resources.ResourceKey; -import net.minecraft.world.level.biome.Biome; - -import com.dfsek.terra.api.properties.Properties; - - -public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInjector.java deleted file mode 100644 index b798ba4b8c..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeInjector.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSpecialEffects; - -import java.util.Locale; -import java.util.Objects; -import java.util.Optional; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; - - -public class NMSBiomeInjector { - - public static Optional> getEntry(Registry registry, ResourceLocation identifier) { - return registry.getOptional(identifier) - .flatMap(registry::getResourceKey) - .flatMap(registry::getHolder); - } - - public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla) - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { - Biome.BiomeBuilder builder = new Biome.BiomeBuilder(); - - builder - .downfall(vanilla.climateSettings.downfall()) - .temperature(vanilla.getBaseTemperature()) - .mobSpawnSettings(vanilla.getMobSettings()) - .generationSettings(vanilla.getGenerationSettings()); - - - BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder(); - - effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier()); - - VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); - - effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor())) - - .waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor())) - - .waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor())) - - .skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor())); - - if(vanillaBiomeProperties.getFoliageColor() == null) { - vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride); - } else { - effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor()); - } - - if(vanillaBiomeProperties.getGrassColor() == null) { - vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride); - } else { - // grass - effects.grassColorOverride(vanillaBiomeProperties.getGrassColor()); - } - - vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound); - vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound); - vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound); - vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic); - vanilla.getAmbientParticle().ifPresent(effects::ambientParticle); - - builder.specialEffects(effects.build()); - - return builder.build(); - } - - public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { - return pack.getID() - .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSChunkGeneratorDelegate.java deleted file mode 100644 index 8ecc904acc..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSChunkGeneratorDelegate.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import com.mojang.serialization.Codec; -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.Beardifier; -import net.minecraft.world.level.levelgen.DensityFunction.SinglePointContext; -import net.minecraft.world.level.levelgen.GenerationStep.Carving; -import net.minecraft.world.level.levelgen.Heightmap.Types; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData; -import org.jetbrains.annotations.NotNull; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import com.dfsek.terra.api.world.info.WorldProperties; -import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions; -import com.dfsek.terra.bukkit.world.BukkitWorldProperties; -import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState; - - -public class NMSChunkGeneratorDelegate extends ChunkGenerator { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); - private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; - - private final ChunkGenerator vanilla; - private final ConfigPack pack; - - private final long seed; - - public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { - super(biomeProvider); - this.delegate = pack.getGeneratorProvider().newInstance(pack); - this.vanilla = vanilla; - this.pack = pack; - this.seed = seed; - } - - @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; - } - - @Override - public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) { - // no-op - } - - @Override - public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig, - @NotNull ChunkAccess chunk) { - // no-op - } - - @Override - public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk, - @NotNull StructureManager structureAccessor) { - vanilla.applyBiomeDecoration(world, chunk, structureAccessor); - } - - @Override - public void spawnOriginalMobs(@NotNull WorldGenRegion region) { - vanilla.spawnOriginalMobs(region); - } - - @Override - public int getGenDepth() { - return vanilla.getGenDepth(); - } - - @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull RandomState noiseConfig, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk) - .thenApply(c -> { - LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class); - if(compatibilityOptions.isBeard()) { - beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()), - biomeProvider, compatibilityOptions); - } - return c; - }); - } - - private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider, - PreLoadCompatibilityOptions compatibilityOptions) { - Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos()); - double threshold = compatibilityOptions.getBeardThreshold(); - double airThreshold = compatibilityOptions.getAirThreshold(); - int xi = chunk.getPos().x << 4; - int zi = chunk.getPos().z << 4; - for(int x = 0; x < 16; x++) { - for(int z = 0; z < 16; z++) { - int depth = 0; - for(int y = world.getMaxHeight(); y >= world.getMinHeight(); y--) { - double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi)); - if(noise > threshold) { - chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate - .getPalette(x + xi, y, z + zi, world, biomeProvider) - .get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false); - depth++; - } else if(noise < airThreshold) { - chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false); - } else { - depth = 0; - } - } - } - } - } - - @Override - public int getSeaLevel() { - return vanilla.getSeaLevel(); - } - - @Override - public int getMinY() { - return vanilla.getMinY(); - } - - @Override - public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - WorldProperties properties = new NMSWorldProperties(seed, world); - int y = properties.getMaxHeight(); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - while(y >= getMinY() && !heightmap.isOpaque().test( - ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { - y--; - } - return y; - } - - @Override - public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) { - BlockState[] array = new BlockState[world.getHeight()]; - WorldProperties properties = new NMSWorldProperties(seed, world); - BiomeProvider biomeProvider = pack.getBiomeProvider(); - for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { - array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) - .getHandle()).getState(); - } - return new NoiseColumn(getMinY(), array); - } - - @Override - public void addDebugScreenInfo(@NotNull List text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) { - - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInitializer.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInitializer.java deleted file mode 100644 index 89cf3b8786..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInitializer.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import org.bukkit.Bukkit; - -import com.dfsek.terra.bukkit.PlatformImpl; -import com.dfsek.terra.bukkit.nms.Initializer; - - -public class NMSInitializer implements Initializer { - @Override - public void initialize(PlatformImpl platform) { - AwfulBukkitHacks.registerBiomes(platform.getRawConfigRegistry()); - Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInjectListener.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInjectListener.java deleted file mode 100644 index ace83ddc7d..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSInjectListener.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.level.chunk.ChunkGenerator; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.world.WorldInitEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.locks.ReentrantLock; - -import com.dfsek.terra.api.config.ConfigPack; -import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; - - -public class NMSInjectListener implements Listener { - private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); - private static final Set INJECTED = new HashSet<>(); - private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); - - @EventHandler - public void onWorldInit(WorldInitEvent event) { - if(!INJECTED.contains(event.getWorld()) && - event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { - INJECT_LOCK.lock(); - INJECTED.add(event.getWorld()); - LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); - CraftWorld craftWorld = (CraftWorld) event.getWorld(); - ServerLevel serverWorld = craftWorld.getHandle(); - - ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); - - ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); - NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed()); - - serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); - - LOGGER.info("Successfully injected into world."); - - INJECT_LOCK.unlock(); - } - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSWorldProperties.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSWorldProperties.java deleted file mode 100644 index 441a1847d0..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSWorldProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.world.level.LevelHeightAccessor; - -import com.dfsek.terra.api.world.info.WorldProperties; - - -public class NMSWorldProperties implements WorldProperties { - private final long seed; - private final LevelHeightAccessor height; - - public NMSWorldProperties(long seed, LevelHeightAccessor height) { - this.seed = seed; - this.height = height; - } - - @Override - public Object getHandle() { - return height; - } - - @Override - public long getSeed() { - return seed; - } - - @Override - public int getMaxHeight() { - return height.getMaxBuildHeight(); - } - - @Override - public int getMinHeight() { - return height.getMinBuildHeight(); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/Reflection.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/Reflection.java deleted file mode 100644 index da7b5c01d9..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/Reflection.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.core.Holder; -import net.minecraft.core.Holder.Reference; -import net.minecraft.core.MappedRegistry; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.StructureManager; -import xyz.jpenilla.reflectionremapper.ReflectionRemapper; -import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldSetter; -import xyz.jpenilla.reflectionremapper.proxy.annotation.MethodName; -import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies; - - -public class Reflection { - public static final MappedRegistryProxy MAPPED_REGISTRY; - public static final StructureManagerProxy STRUCTURE_MANAGER; - - public static final ReferenceProxy REFERENCE; - - static { - ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); - ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, - Reflection.class.getClassLoader()); - - MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); - STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class); - REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class); - } - - - @Proxies(MappedRegistry.class) - public interface MappedRegistryProxy { - @FieldSetter("frozen") - void setFrozen(MappedRegistry instance, boolean frozen); - } - - - @Proxies(StructureManager.class) - public interface StructureManagerProxy { - @FieldGetter("level") - LevelAccessor getLevel(StructureManager instance); - } - - - @Proxies(Holder.Reference.class) - public interface ReferenceProxy { - @MethodName("bindValue") - void invokeBindValue(Reference instance, T value); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/RegistryFetcher.java b/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/RegistryFetcher.java deleted file mode 100644 index 52bec1b1b2..0000000000 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/RegistryFetcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; - -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.server.dedicated.DedicatedServer; -import net.minecraft.world.level.biome.Biome; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R2.CraftServer; - - -public class RegistryFetcher { - private static Registry getRegistry(ResourceKey> key) { - CraftServer craftserver = (CraftServer) Bukkit.getServer(); - DedicatedServer dedicatedserver = craftserver.getServer(); - return dedicatedserver - .registryAccess() - .registryOrThrow(key); - } - - public static Registry biomeRegistry() { - return getRegistry(Registries.BIOME); - } -} diff --git a/platforms/bukkit/nms/v1_20_R2/build.gradle.kts b/platforms/bukkit/nms/v1_21/build.gradle.kts similarity index 77% rename from platforms/bukkit/nms/v1_20_R2/build.gradle.kts rename to platforms/bukkit/nms/v1_21/build.gradle.kts index 6881c96ca1..d52f1d1691 100644 --- a/platforms/bukkit/nms/v1_20_R2/build.gradle.kts +++ b/platforms/bukkit/nms/v1_21/build.gradle.kts @@ -1,9 +1,5 @@ apply(plugin = "io.papermc.paperweight.userdev") -repositories { - maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") -} - dependencies { api(project(":platforms:bukkit:common")) paperDevBundle(Versions.Bukkit.paperDevBundle) diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/AwfulBukkitHacks.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/AwfulBukkitHacks.java similarity index 91% rename from platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/AwfulBukkitHacks.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/AwfulBukkitHacks.java index 8023ae4522..42d6833942 100644 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/AwfulBukkitHacks.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/AwfulBukkitHacks.java @@ -1,10 +1,10 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; +package com.dfsek.terra.bukkit.nms.v1_21; import com.google.common.collect.ImmutableMap; -import com.mojang.serialization.Lifecycle; import net.minecraft.core.Holder; import net.minecraft.core.Holder.Reference; import net.minecraft.core.MappedRegistry; +import net.minecraft.core.RegistrationInfo; import net.minecraft.core.WritableRegistry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; @@ -41,15 +41,16 @@ public static void registerBiomes(ConfigRegistry configRegistry) { try { BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); - ResourceLocation vanillaMinecraftKey = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); + ResourceLocation vanillaMinecraftKey = ResourceLocation.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(), + vanillaBukkitKey.getKey()); Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey))); ResourceKey delegateKey = ResourceKey.create( Registries.BIOME, - new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key)) + ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key)) ); - Reference holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable()); + Reference holder = biomeRegistry.register(delegateKey, platform, RegistrationInfo.BUILT_IN); Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder. platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInfo.java similarity index 83% rename from platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInfo.java index 639c9eaedd..5bf85aa6de 100644 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSBiomeInfo.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInfo.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; +package com.dfsek.terra.bukkit.nms.v1_21; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.biome.Biome; diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInjector.java similarity index 98% rename from platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInjector.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInjector.java index 8c13d05b14..e6d1f78695 100644 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSBiomeInjector.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeInjector.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; +package com.dfsek.terra.bukkit.nms.v1_21; import net.minecraft.core.Holder; import net.minecraft.core.Registry; diff --git a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeProvider.java similarity index 73% rename from platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeProvider.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeProvider.java index 1521a3582e..8abe26a51b 100644 --- a/platforms/bukkit/nms/v1_20_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R2/NMSBiomeProvider.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSBiomeProvider.java @@ -1,6 +1,6 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R2; +package com.dfsek.terra.bukkit.nms.v1_21; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.world.level.biome.Biome; @@ -35,8 +35,12 @@ protected Stream> collectPossibleBiomes() { } @Override - protected @NotNull Codec codec() { - return BiomeSource.CODEC; + protected @NotNull MapCodec codec() { + return MapCodec.assumeMapUnsafe(BiomeSource.CODEC); + // return MapCodec.unit(null); + // BuiltInRegistries.BIOME_SOURCE.byNameCodec().dispatchMap(this::codec, Function.identity()); + // BuiltInRegistries.BIOME_SOURCE.byNameCodec().dispatchStable(BiomeSource::codec, Function.identity()); + // return BiomeSource.CODEC; } @Override diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSChunkGeneratorDelegate.java similarity index 90% rename from platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSChunkGeneratorDelegate.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSChunkGeneratorDelegate.java index 565d0cbc4d..16097df272 100644 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/NMSChunkGeneratorDelegate.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSChunkGeneratorDelegate.java @@ -1,6 +1,6 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; +package com.dfsek.terra.bukkit.nms.v1_21; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.core.BlockPos; import net.minecraft.server.level.WorldGenRegion; import net.minecraft.world.level.LevelAccessor; @@ -19,14 +19,13 @@ import net.minecraft.world.level.levelgen.Heightmap.Types; import net.minecraft.world.level.levelgen.RandomState; import net.minecraft.world.level.levelgen.blending.Blender; -import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData; +import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; @@ -54,8 +53,8 @@ public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBio } @Override - protected @NotNull Codec codec() { - return ChunkGenerator.CODEC; + protected @NotNull MapCodec codec() { + return MapCodec.assumeMapUnsafe(ChunkGenerator.CODEC); } @Override @@ -87,10 +86,10 @@ public int getGenDepth() { } @Override - public @NotNull CompletableFuture fillFromNoise(@NotNull Executor executor, @NotNull Blender blender, - @NotNull RandomState noiseConfig, - @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { - return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk) + public CompletableFuture fillFromNoise(@NotNull Blender blender, + @NotNull RandomState noiseConfig, + @NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) { + return vanilla.fillFromNoise(blender, noiseConfig, structureAccessor, chunk) .thenApply(c -> { LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor); BiomeProvider biomeProvider = pack.getBiomeProvider(); diff --git a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInitializer.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInitializer.java similarity index 90% rename from platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInitializer.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInitializer.java index f724b89f0f..18f1a058f9 100644 --- a/platforms/bukkit/nms/v1_18_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_18_R2/NMSInitializer.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInitializer.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.bukkit.nms.v1_18_R2; +package com.dfsek.terra.bukkit.nms.v1_21; import org.bukkit.Bukkit; diff --git a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInjectListener.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInjectListener.java similarity index 68% rename from platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInjectListener.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInjectListener.java index 78da74f655..a25638594e 100644 --- a/platforms/bukkit/nms/v1_19_R3/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R3/NMSInjectListener.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSInjectListener.java @@ -1,9 +1,11 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R3; +package com.dfsek.terra.bukkit.nms.v1_21; +import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.status.WorldGenContext; import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.world.WorldInitEvent; @@ -15,6 +17,7 @@ import java.util.concurrent.locks.ReentrantLock; import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.util.reflection.ReflectionUtil; import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; @@ -37,8 +40,15 @@ public void onWorldInit(WorldInitEvent event) { ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator(); NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed()); - - serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); + ChunkMap chunkMap = serverWorld.getChunkSource().chunkMap; + WorldGenContext worldGenContext = chunkMap.worldGenContext; + Reflection.CHUNKMAP.setWorldGenContext(chunkMap, new WorldGenContext( + worldGenContext.level(), + new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()), + worldGenContext.structureManager(), + worldGenContext.lightEngine(), + worldGenContext.mainThreadMailBox() + )); LOGGER.info("Successfully injected into world."); diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSWorldProperties.java similarity index 94% rename from platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSWorldProperties.java index 9e1989451a..7860cf5308 100644 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/NMSWorldProperties.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/NMSWorldProperties.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; +package com.dfsek.terra.bukkit.nms.v1_21; import net.minecraft.world.level.LevelHeightAccessor; diff --git a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/Reflection.java similarity index 80% rename from platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/Reflection.java index d0f9332583..a6f4ea9ba1 100644 --- a/platforms/bukkit/nms/v1_19_R2/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R2/Reflection.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/Reflection.java @@ -1,10 +1,12 @@ -package com.dfsek.terra.bukkit.nms.v1_19_R2; +package com.dfsek.terra.bukkit.nms.v1_21; import net.minecraft.core.Holder; import net.minecraft.core.Holder.Reference; import net.minecraft.core.MappedRegistry; +import net.minecraft.server.level.ChunkMap; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.chunk.status.WorldGenContext; import xyz.jpenilla.reflectionremapper.ReflectionRemapper; import xyz.jpenilla.reflectionremapper.proxy.ReflectionProxyFactory; import xyz.jpenilla.reflectionremapper.proxy.annotation.FieldGetter; @@ -19,6 +21,8 @@ public class Reflection { public static final ReferenceProxy REFERENCE; + public static final ChunkMapProxy CHUNKMAP; + static { ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar(); ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, @@ -27,6 +31,7 @@ public class Reflection { MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class); STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class); REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class); + CHUNKMAP = reflectionProxyFactory.reflectionProxy(ChunkMapProxy.class); } @@ -49,4 +54,10 @@ public interface ReferenceProxy { @MethodName("bindValue") void invokeBindValue(Reference instance, T value); } + + @Proxies(ChunkMap.class) + public interface ChunkMapProxy { + @FieldSetter("worldGenContext") + void setWorldGenContext(ChunkMap instance, WorldGenContext worldGenContext); + } } diff --git a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/RegistryFetcher.java b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/RegistryFetcher.java similarity index 88% rename from platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/RegistryFetcher.java rename to platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/RegistryFetcher.java index c7d77462d3..0377eea0fe 100644 --- a/platforms/bukkit/nms/v1_20_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_20_R1/RegistryFetcher.java +++ b/platforms/bukkit/nms/v1_21/src/main/java/com/dfsek/terra/bukkit/nms/v1_21/RegistryFetcher.java @@ -1,4 +1,4 @@ -package com.dfsek.terra.bukkit.nms.v1_20_R1; +package com.dfsek.terra.bukkit.nms.v1_21; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; @@ -6,7 +6,7 @@ import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.world.level.biome.Biome; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_20_R1.CraftServer; +import org.bukkit.craftbukkit.CraftServer; public class RegistryFetcher { diff --git a/platforms/fabric/build.gradle.kts b/platforms/fabric/build.gradle.kts index 3b977d8af8..73d2a7d647 100644 --- a/platforms/fabric/build.gradle.kts +++ b/platforms/fabric/build.gradle.kts @@ -3,7 +3,6 @@ import java.util.* plugins { id("dev.architectury.loom") version Versions.Mod.architecuryLoom id("architectury-plugin") version Versions.Mod.architecturyPlugin - id("io.github.juuxel.loom-vineflower") version Versions.Mod.loomVineflower } architectury { @@ -27,8 +26,10 @@ dependencies { modImplementation("net.fabricmc:fabric-loader:${Versions.Mod.fabricLoader}") - modImplementation("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) - include("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) + modImplementation("org.incendo", "cloud-fabric", Versions.Libraries.cloudFabric) + include("org.incendo", "cloud-fabric", Versions.Libraries.cloudFabric) + + modRuntimeOnly("net.fabricmc.fabric-api", "fabric-api", Versions.Fabric.fabricAPI) } loom { @@ -37,6 +38,15 @@ loom { mixin { defaultRefmapName.set("terra.fabric.refmap.json") } + + launches { + named("client") { + property("fabric.log.level", "info") + } + named("server") { + property("fabric.log.level", "info") + } + } } @@ -44,10 +54,6 @@ loom { addonDir(project.file("./run/config/Terra/addons"), tasks.named("configureLaunch").get()) tasks { - compileJava { - options.release.set(17) - } - remapJar { dependsOn("installAddons") diff --git a/platforms/fabric/src/main/resources/fabric.mod.json b/platforms/fabric/src/main/resources/fabric.mod.json index bfb5727101..592d4021a6 100644 --- a/platforms/fabric/src/main/resources/fabric.mod.json +++ b/platforms/fabric/src/main/resources/fabric.mod.json @@ -5,7 +5,13 @@ "name": "Terra", "description": "@DESCRIPTION@", "authors": [ - "dfsek" + "dfsek", + "duplexsystem", + "Astrash", + "solonovamax", + "Sancires", + "Aureus", + "RogueShade" ], "contact": { "homepage": "@WIKI@", @@ -26,9 +32,9 @@ "terra.common.mixins.json" ], "depends": { - "fabricloader": ">=0.14.2", - "java": ">=17", - "minecraft": "1.20.x", + "fabricloader": ">=0.16.5", + "java": ">=21", + "minecraft": ">=1.21.1", "fabric": "*" } } \ No newline at end of file diff --git a/platforms/fabric/src/main/resources/terra.fabric.mixins.json b/platforms/fabric/src/main/resources/terra.fabric.mixins.json index f97889f6d9..4778acf1b3 100644 --- a/platforms/fabric/src/main/resources/terra.fabric.mixins.json +++ b/platforms/fabric/src/main/resources/terra.fabric.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.dfsek.terra.fabric.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ ], "client": [ diff --git a/platforms/forge/build.gradle.kts b/platforms/forge/build.gradle.kts.disabled similarity index 100% rename from platforms/forge/build.gradle.kts rename to platforms/forge/build.gradle.kts.disabled diff --git a/platforms/forge/src/main/resources/terra.forge.mixins.json b/platforms/forge/src/main/resources/terra.forge.mixins.json index 25c1c470ed..095ea92348 100644 --- a/platforms/forge/src/main/resources/terra.forge.mixins.json +++ b/platforms/forge/src/main/resources/terra.forge.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.dfsek.terra.forge.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "lifecycle.NoiseConfigMixin" ], diff --git a/platforms/merged/build.gradle.kts b/platforms/merged/build.gradle.kts index ec9e56f878..aab37e093c 100644 --- a/platforms/merged/build.gradle.kts +++ b/platforms/merged/build.gradle.kts @@ -13,7 +13,7 @@ val dump = tasks.create("dumpDependents") { doFirst { taskSet.forEach { val resource = File(resourcesDir, it.archiveFileName.get()) - println("Including archive " + it.archiveFileName.orNull + " in directory " + resource.absolutePath) + logger.info("Including archive " + it.archiveFileName.orNull + " in directory " + resource.absolutePath) it.archiveFile.get().asFile.copyTo(resource, true) } } @@ -32,6 +32,6 @@ afterEvaluate { } tasks["dumpDependents"].dependsOn(task) taskSet.add(task) - println("Merged JAR will incorporate task ${task.name} from platform ${it.name}.") + logger.info("Merged JAR will incorporate task ${task.name} from platform ${it.name}.") } } \ No newline at end of file diff --git a/platforms/mixin-common/build.gradle.kts b/platforms/mixin-common/build.gradle.kts index a6b4e72311..2fb92233c6 100644 --- a/platforms/mixin-common/build.gradle.kts +++ b/platforms/mixin-common/build.gradle.kts @@ -1,7 +1,6 @@ plugins { id("dev.architectury.loom") version Versions.Mod.architecuryLoom id("architectury-plugin") version Versions.Mod.architecturyPlugin - id("io.github.juuxel.loom-vineflower") version Versions.Mod.loomVineflower } loom { @@ -24,7 +23,7 @@ dependencies { } architectury { - common("fabric", "forge") + common("fabric") minecraft = Versions.Mod.minecraft } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java index 25c78c228c..09681f6b61 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/ModPlatform.java @@ -3,6 +3,7 @@ import com.dfsek.tectonic.api.TypeRegistry; import com.dfsek.tectonic.api.depth.DepthTracker; import com.dfsek.tectonic.api.exception.LoadException; +import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnGroup; import net.minecraft.registry.Registry; @@ -44,7 +45,6 @@ import com.dfsek.terra.mod.config.SoundEventTemplate; import com.dfsek.terra.mod.config.SpawnCostConfig; import com.dfsek.terra.mod.config.SpawnEntryTemplate; -import com.dfsek.terra.mod.config.SpawnGroupTemplate; import com.dfsek.terra.mod.config.SpawnSettingsTemplate; import com.dfsek.terra.mod.config.SpawnTypeConfig; import com.dfsek.terra.mod.config.VillagerTypeTemplate; @@ -82,6 +82,7 @@ public void register(TypeRegistry registry) { .registerLoader(GrassColorModifier.class, (type, o, loader, depthTracker) -> TemperatureModifier.valueOf(((String) o).toUpperCase( Locale.ROOT))) + .registerLoader(SpawnGroup.class, (type, o, loader, depthTracker) -> SpawnGroup.valueOf((String) o)) .registerLoader(BiomeParticleConfig.class, BiomeParticleConfigTemplate::new) .registerLoader(SoundEvent.class, SoundEventTemplate::new) .registerLoader(BiomeMoodSound.class, BiomeMoodSoundTemplate::new) @@ -90,7 +91,6 @@ public void register(TypeRegistry registry) { .registerLoader(EntityType.class, EntityTypeTemplate::new) .registerLoader(SpawnCostConfig.class, SpawnCostConfig::new) .registerLoader(SpawnEntry.class, SpawnEntryTemplate::new) - .registerLoader(SpawnGroup.class, SpawnGroupTemplate::new) .registerLoader(SpawnTypeConfig.class, SpawnTypeConfig::new) .registerLoader(SpawnSettings.class, SpawnSettingsTemplate::new) .registerLoader(VillagerType.class, VillagerTypeTemplate::new); @@ -117,6 +117,8 @@ protected Iterable platformAddon() { public abstract Registry multiNoiseBiomeSourceParameterListRegistry(); + public abstract Registry enchantmentRegistry(); + @Override public @NotNull WorldHandle getWorldHandle() { return worldHandle; @@ -126,4 +128,6 @@ protected Iterable platformAddon() { public @NotNull ItemHandle getItemHandle() { return itemHandle; } + + } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java index 97c8c8ed7a..457566444d 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/BiomeParticleConfigTemplate.java @@ -7,6 +7,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.argument.ParticleEffectArgumentType; import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryWrapper; import net.minecraft.world.biome.BiomeParticleConfig; @@ -27,7 +28,8 @@ public BiomeParticleConfig get() { try { return new BiomeParticleConfig( - ParticleEffectArgumentType.readParameters(new StringReader(particle), Registries.PARTICLE_TYPE.getReadOnlyWrapper()), + ParticleEffectArgumentType.readParameters(new StringReader(particle), + (RegistryWrapper.WrapperLookup) Registries.PARTICLE_TYPE.getReadOnlyWrapper()), probability); } catch(CommandSyntaxException e) { throw new RuntimeException(e); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnGroupTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnGroupTemplate.java deleted file mode 100644 index 0ae2047f2c..0000000000 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnGroupTemplate.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.dfsek.terra.mod.config; - -import com.dfsek.tectonic.api.config.template.annotations.Default; -import com.dfsek.tectonic.api.config.template.annotations.Value; -import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; -import net.minecraft.entity.SpawnGroup; - - -public class SpawnGroupTemplate implements ObjectTemplate { - @Value("group") - @Default - private String group = null; - - @Override - public SpawnGroup get() { - return SpawnGroup.valueOf(group); - } -} diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnSettingsTemplate.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnSettingsTemplate.java index 9392e94e10..a0e8932e50 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnSettingsTemplate.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnSettingsTemplate.java @@ -3,7 +3,9 @@ import com.dfsek.tectonic.api.config.template.annotations.Default; import com.dfsek.tectonic.api.config.template.annotations.Value; import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; +import net.minecraft.entity.SpawnGroup; import net.minecraft.world.biome.SpawnSettings; +import net.minecraft.world.biome.SpawnSettings.SpawnEntry; import java.util.List; @@ -25,7 +27,10 @@ public class SpawnSettingsTemplate implements ObjectTemplate { public SpawnSettings get() { SpawnSettings.Builder builder = new SpawnSettings.Builder(); for(SpawnTypeConfig spawn : spawns) { - builder.spawn(spawn.getGroup(), spawn.getEntry()); + SpawnGroup group = spawn.getGroup(); + for(SpawnEntry entry : spawn.getEntry()) { + builder.spawn(group, entry); + } } for(SpawnCostConfig cost : costs) { builder.spawnCost(cost.getType(), cost.getMass(), cost.getGravity()); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnTypeConfig.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnTypeConfig.java index 9384f991d3..0eba7ca67a 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnTypeConfig.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/config/SpawnTypeConfig.java @@ -6,21 +6,23 @@ import net.minecraft.entity.SpawnGroup; import net.minecraft.world.biome.SpawnSettings.SpawnEntry; +import java.util.List; + public class SpawnTypeConfig implements ObjectTemplate { @Value("group") @Default private SpawnGroup group = null; - @Value("entry") + @Value("entries") @Default - private SpawnEntry entry = null; + private List entry = null; public SpawnGroup getGroup() { return group; } - public SpawnEntry getEntry() { + public List getEntry() { return entry; } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java index 595f5ec5b8..ab7604fe50 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/data/Codecs.java @@ -1,6 +1,7 @@ package com.dfsek.terra.mod.data; import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.world.gen.chunk.ChunkGeneratorSettings; @@ -32,15 +33,15 @@ public final class Codecs { "No such config pack " + id))))); - public static final Codec TERRA_BIOME_SOURCE = RecordCodecBuilder - .create(instance -> instance.group( + public static final MapCodec TERRA_BIOME_SOURCE = RecordCodecBuilder + .mapCodec(instance -> instance.group( CONFIG_PACK.fieldOf("pack") .stable() .forGetter(TerraBiomeSource::getPack)) .apply(instance, instance.stable(TerraBiomeSource::new))); - public static final Codec MINECRAFT_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder - .create( + public static final MapCodec MINECRAFT_CHUNK_GENERATOR_WRAPPER = RecordCodecBuilder + .mapCodec( instance -> instance.group( TERRA_BIOME_SOURCE.fieldOf("biome_source") .stable() diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java index 899b007f0b..46f5601ded 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/MinecraftChunkGeneratorWrapper.java @@ -17,7 +17,7 @@ package com.dfsek.terra.mod.generation; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.registry.entry.RegistryEntry; @@ -48,7 +48,6 @@ import java.util.List; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; @@ -85,7 +84,7 @@ public MinecraftChunkGeneratorWrapper(TerraBiomeSource biomeSource, ConfigPack c } @Override - protected Codec getCodec() { + protected MapCodec getCodec() { return Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER; } @@ -110,10 +109,9 @@ public int getWorldHeight() { return settings.value().generationShapeConfig().height(); } - @Override - public CompletableFuture populateNoise(Executor executor, Blender blender, NoiseConfig noiseConfig, - StructureAccessor structureAccessor, Chunk chunk) { + public CompletableFuture populateNoise(Blender blender, NoiseConfig noiseConfig, StructureAccessor structureAccessor, + Chunk chunk) { return CompletableFuture.supplyAsync(() -> { ProtoWorld world = (ProtoWorld) ((StructureAccessorAccessor) structureAccessor).getWorld(); BiomeProvider biomeProvider = pack.getBiomeProvider(); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java index 7aa5d8aea2..81651ece8c 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/generation/TerraBiomeSource.java @@ -17,7 +17,7 @@ package com.dfsek.terra.mod.generation; -import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.source.BiomeSource; @@ -47,7 +47,7 @@ public TerraBiomeSource(ConfigPack pack) { } @Override - protected Codec getCodec() { + protected MapCodec getCodec() { return Codecs.TERRA_BIOME_SOURCE; } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java index 541e764aba..c9ef02f378 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftItemHandle.java @@ -21,14 +21,15 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.argument.ItemStackArgumentType; -import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.RegistryWrapper.Impl; import net.minecraft.util.Identifier; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; +import java.util.stream.Stream; import com.dfsek.terra.api.handle.ItemHandle; import com.dfsek.terra.api.inventory.Item; @@ -43,8 +44,13 @@ public Item createItem(String data) { try { return (Item) new ItemStackArgumentType(new CommandRegistryAccess() { @Override - public RegistryWrapper createWrapper(RegistryKey> registryRef) { - return CommonPlatform.get().getServer().getRegistryManager().getWrapperOrThrow(registryRef); + public Stream>> streamAllRegistryKeys() { + return CommonPlatform.get().getServer().getRegistryManager().streamAllRegistryKeys(); + } + + @Override + public Optional> getOptionalWrapper(RegistryKey> registryRef) { + return Optional.of(CommonPlatform.get().getServer().getRegistryManager().getWrapperOrThrow(registryRef)); } }).parse(new StringReader(data)).getItem(); } catch(CommandSyntaxException e) { @@ -54,11 +60,12 @@ public RegistryWrapper createWrapper(RegistryKey> r @Override public Enchantment getEnchantment(String id) { - return (Enchantment) (Registries.ENCHANTMENT.get(Identifier.tryParse(id))); + return (Enchantment) (Object) (CommonPlatform.get().enchantmentRegistry().get(Identifier.tryParse(id))); } @Override public Set getEnchantments() { - return Registries.ENCHANTMENT.stream().map(enchantment -> (Enchantment) enchantment).collect(Collectors.toSet()); + return CommonPlatform.get().enchantmentRegistry().stream().map(enchantment -> (Enchantment) (Object) enchantment).collect( + Collectors.toSet()); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java index 52ea52dfa8..c36744d183 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/handle/MinecraftWorldHandle.java @@ -23,6 +23,8 @@ import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.entity.EntityType; @@ -31,11 +33,21 @@ public class MinecraftWorldHandle implements WorldHandle { + private static final BlockState AIR = (BlockState) Blocks.AIR.getDefaultState(); + private static final Logger logger = LoggerFactory.getLogger(MinecraftWorldHandle.class); + @Override public @NotNull BlockState createBlockState(@NotNull String data) { try { + if(data.equals("minecraft:grass")) { //TODO: remove in 7.0 + data = "minecraft:short_grass"; + logger.warn( + "Translating minecraft:grass to minecraft:short_grass. In 1.20.3 minecraft:grass was renamed to minecraft:short_grass" + + ". You are advised to perform this rename in your config packs as this translation will be removed in the next major " + + "version of Terra."); + } net.minecraft.block.BlockState state = BlockArgumentParser.block(Registries.BLOCK.getReadOnlyWrapper(), data, true) .blockState(); if(state == null) throw new IllegalArgumentException("Invalid data: " + data); @@ -52,6 +64,16 @@ public class MinecraftWorldHandle implements WorldHandle { @Override public @NotNull EntityType getEntity(@NotNull String id) { + if(!id.contains(":")) { //TODO: remove in 7.0 + String newid = "minecraft:" + id.toLowerCase(); + ; + logger.warn( + "Translating " + id + " to " + newid + ". In 1.20.3 entity parsing was reworked" + + ". You are advised to perform this rename in your config packs as this translation will be removed in the next major " + + "version of Terra."); + id = newid; + } + if(!id.contains(":")) throw new IllegalArgumentException("Invalid entity identifier " + id); Identifier identifier = Identifier.tryParse(id); if(identifier == null) identifier = Identifier.tryParse(id); return (EntityType) Registries.ENTITY_TYPE.get(identifier); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/MobSpawnerLogicAccessor.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/MobSpawnerLogicAccessor.java index 5289cd4274..002b5c25ba 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/MobSpawnerLogicAccessor.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/access/MobSpawnerLogicAccessor.java @@ -17,8 +17,8 @@ package com.dfsek.terra.mod.mixin.access; -import net.minecraft.world.MobSpawnerEntry; -import net.minecraft.world.MobSpawnerLogic; +import net.minecraft.block.spawner.MobSpawnerEntry; +import net.minecraft.block.spawner.MobSpawnerLogic; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java index 1b882e5fd5..15e8fab349 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/entity/MobSpawnerBlockEntityMixin.java @@ -21,11 +21,11 @@ import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.MobSpawnerBlockEntity; +import net.minecraft.block.spawner.MobSpawnerLogic; import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.random.Random; -import net.minecraft.world.MobSpawnerLogic; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; @@ -49,6 +49,7 @@ private MobSpawnerBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockS @Shadow public abstract MobSpawnerLogic getLogic(); + //method_46408 @Shadow public abstract void setEntityType(net.minecraft.entity.EntityType entityType, Random random); @@ -58,7 +59,13 @@ private MobSpawnerBlockEntityMixin(BlockEntityType type, BlockPos pos, BlockS } public void terra$setSpawnedType(@NotNull EntityType creatureType) { - setEntityType((net.minecraft.entity.EntityType) creatureType, world.getRandom()); + Random rand; + if(hasWorld()) { + rand = world.getRandom(); + } else { + rand = Random.create(); + } + setEntityType((net.minecraft.entity.EntityType) creatureType, rand); } public int terra$getDelay() { diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java index 7053dd4f51..4243bf9428 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/block/state/BlockStateMixin.java @@ -1,8 +1,8 @@ package com.dfsek.terra.mod.mixin.implementations.terra.block.state; -import com.google.common.collect.ImmutableMap; import com.mojang.serialization.MapCodec; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import net.minecraft.block.AbstractBlock.AbstractBlockState; import net.minecraft.block.Block; import net.minecraft.registry.Registries; @@ -24,7 +24,7 @@ @Mixin(AbstractBlockState.class) @Implements(@Interface(iface = BlockState.class, prefix = "terra$")) public abstract class BlockStateMixin extends State { - private BlockStateMixin(Block owner, ImmutableMap, Comparable> entries, + private BlockStateMixin(Block owner, Reference2ObjectArrayMap, Comparable> entries, MapCodec codec) { super(owner, entries, codec); } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/entity/EntityMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/entity/EntityMixin.java index 3225cd4a6a..0b2f470176 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/entity/EntityMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/entity/EntityMixin.java @@ -39,14 +39,14 @@ public abstract class EntityMixin { private BlockPos blockPos; @Shadow - public abstract void teleport(double destX, double destY, double destZ); + public abstract void updatePosition(double destX, double destY, double destZ); public Vector3 terra$position() { return MinecraftAdapter.adapt(blockPos); } public void terra$position(Vector3 location) { - teleport(location.getX(), location.getY(), location.getZ()); + updatePosition(location.getX(), location.getY(), location.getZ()); } public ServerWorld terra$world() { diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemMixin.java index 78593ecb1a..e8832c2149 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemMixin.java @@ -30,7 +30,7 @@ @Implements(@Interface(iface = com.dfsek.terra.api.inventory.Item.class, prefix = "terra$")) public abstract class ItemMixin { @Shadow - public abstract int getMaxDamage(); + public abstract net.minecraft.item.ItemStack getDefaultStack(); @SuppressWarnings("ConstantConditions") public ItemStack terra$newItemStack(int amount) { @@ -38,6 +38,7 @@ public abstract class ItemMixin { } public double terra$getMaxDurability() { - return getMaxDamage(); + //TODO verify this is correct + return getDefaultStack().getMaxDamage(); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemStackMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemStackMixin.java index 089a6db1dc..76121f64b8 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemStackMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/item/ItemStackMixin.java @@ -17,9 +17,11 @@ package com.dfsek.terra.mod.mixin.implementations.terra.inventory.item; +import net.minecraft.component.ComponentChanges; +import net.minecraft.component.ComponentMap; +import net.minecraft.component.ComponentMapImpl; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Intrinsic; @@ -33,6 +35,10 @@ @Mixin(ItemStack.class) @Implements(@Interface(iface = com.dfsek.terra.api.inventory.ItemStack.class, prefix = "terra$")) public abstract class ItemStackMixin { + @Shadow + @Final + private ComponentMapImpl components; + @Shadow public abstract int getCount(); @@ -46,7 +52,7 @@ public abstract class ItemStackMixin { public abstract boolean isDamageable(); @Shadow - public abstract void setNbt(@Nullable NbtCompound tag); + public abstract ComponentMap getComponents(); public int terra$getAmount() { return getCount(); @@ -66,7 +72,13 @@ public abstract class ItemStackMixin { @SuppressWarnings("ConstantConditions") public void terra$setItemMeta(ItemMeta meta) { - setNbt(((ItemStack) (Object) meta).getNbt()); + ComponentChanges.Builder builder = ComponentChanges.builder(); + this.getComponents().getTypes().forEach(builder::remove); + + ComponentMap components = ((ItemStack) (Object) meta).getComponents(); + components.forEach(builder::add); + + this.components.applyChanges(builder.build()); } @Intrinsic diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/EnchantmentMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/EnchantmentMixin.java index 24b096c856..8f58fb9d88 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/EnchantmentMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/EnchantmentMixin.java @@ -18,7 +18,9 @@ package com.dfsek.terra.mod.mixin.implementations.terra.inventory.meta; import net.minecraft.enchantment.Enchantment; -import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Mixin; @@ -27,16 +29,20 @@ import java.util.Objects; import com.dfsek.terra.api.inventory.ItemStack; +import com.dfsek.terra.mod.CommonPlatform; + +import static net.minecraft.enchantment.Enchantment.canBeCombined; @Mixin(Enchantment.class) @Implements(@Interface(iface = com.dfsek.terra.api.inventory.item.Enchantment.class, prefix = "terra$")) public abstract class EnchantmentMixin { @Shadow - public abstract boolean isAcceptableItem(net.minecraft.item.ItemStack stack); + @Final + private RegistryEntryList exclusiveSet; @Shadow - public abstract boolean canCombine(Enchantment other); + public abstract boolean isAcceptableItem(net.minecraft.item.ItemStack stack); @SuppressWarnings("ConstantConditions") public boolean terra$canEnchantItem(ItemStack itemStack) { @@ -44,10 +50,10 @@ public abstract class EnchantmentMixin { } public boolean terra$conflictsWith(com.dfsek.terra.api.inventory.item.Enchantment other) { - return !canCombine((Enchantment) other); + return canBeCombined(RegistryEntry.of((Enchantment) (Object) this), RegistryEntry.of((Enchantment) (Object) other)); } public String terra$getID() { - return Objects.requireNonNull(Registries.ENCHANTMENT.getId((Enchantment) (Object) this)).toString(); + return Objects.requireNonNull(CommonPlatform.get().enchantmentRegistry().getId((Enchantment) (Object) this)).toString(); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/ItemStackMetaMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/ItemStackMetaMixin.java index a6307b02ca..91a487d0b1 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/ItemStackMetaMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/inventory/meta/ItemStackMetaMixin.java @@ -17,10 +17,9 @@ package com.dfsek.terra.mod.mixin.implementations.terra.inventory.meta; +import net.minecraft.component.type.ItemEnchantmentsComponent; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtList; -import net.minecraft.registry.Registries; +import net.minecraft.registry.entry.RegistryEntry; import org.spongepowered.asm.mixin.Implements; import org.spongepowered.asm.mixin.Interface; import org.spongepowered.asm.mixin.Intrinsic; @@ -42,13 +41,14 @@ public abstract class ItemStackMetaMixin { public abstract boolean hasEnchantments(); @Shadow - public abstract NbtList getEnchantments(); + public abstract ItemEnchantmentsComponent getEnchantments(); @Shadow - public abstract void addEnchantment(net.minecraft.enchantment.Enchantment enchantment, int level); + public abstract void addEnchantment(RegistryEntry enchantment, int level); public void terra$addEnchantment(Enchantment enchantment, int level) { - addEnchantment((net.minecraft.enchantment.Enchantment) enchantment, level); + ; + addEnchantment(RegistryEntry.of((net.minecraft.enchantment.Enchantment) (Object) enchantment), level); } @Intrinsic(displace = true) @@ -56,9 +56,10 @@ public abstract class ItemStackMetaMixin { if(!hasEnchantments()) return Collections.emptyMap(); Map map = new HashMap<>(); - getEnchantments().forEach(enchantment -> { - NbtCompound eTag = (NbtCompound) enchantment; - map.put((Enchantment) Registries.ENCHANTMENT.get(eTag.getInt("id")), eTag.getInt("lvl")); + ItemEnchantmentsComponent enchantments = getEnchantments(); + enchantments.getEnchantments().forEach(enchantment -> { + net.minecraft.enchantment.Enchantment enchantmentValue = enchantment.value(); + map.put((Enchantment) (Object) enchantmentValue, enchantments.getLevel(RegistryEntry.of(enchantmentValue))); }); return map; } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/world/ChunkRegionMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/world/ChunkRegionMixin.java index 82080579ba..70a62ae797 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/world/ChunkRegionMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/implementations/terra/world/ChunkRegionMixin.java @@ -19,11 +19,12 @@ import net.minecraft.block.FluidBlock; import net.minecraft.fluid.Fluid; +import net.minecraft.util.collection.BoundedRegionArray; import net.minecraft.util.math.BlockPos; import net.minecraft.world.ChunkRegion; import net.minecraft.world.WorldAccess; import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.ChunkGenerationStep; import net.minecraft.world.tick.MultiTickScheduler; import net.minecraft.world.tick.OrderedTick; import org.spongepowered.asm.mixin.Final; @@ -36,8 +37,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import java.util.List; - import com.dfsek.terra.api.block.entity.BlockEntity; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; @@ -48,6 +47,7 @@ import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator; import com.dfsek.terra.api.world.chunk.generation.ProtoWorld; import com.dfsek.terra.mod.generation.MinecraftChunkGeneratorWrapper; +import com.dfsek.terra.mod.mixin.invoke.FluidBlockInvoker; import com.dfsek.terra.mod.util.MinecraftUtil; @@ -74,10 +74,10 @@ public abstract class ChunkRegionMixin { @Inject(at = @At("RETURN"), - method = "(Lnet/minecraft/server/world/ServerWorld;Ljava/util/List;Lnet/minecraft/world/chunk/ChunkStatus;I)V") - public void injectConstructor(net.minecraft.server.world.ServerWorld world, List list, - ChunkStatus chunkStatus, int i, - CallbackInfo ci) { + method = "(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/util/collection/BoundedRegionArray;" + + "Lnet/minecraft/world/chunk/ChunkGenerationStep;Lnet/minecraft/world/chunk/Chunk;)V") + public void injectConstructor(net.minecraft.server.world.ServerWorld world, BoundedRegionArray chunks, + ChunkGenerationStep generationStep, Chunk centerPos, CallbackInfo ci) { this.terra$config = ((ServerWorld) world).getPack(); } @@ -88,7 +88,7 @@ public void injectConstructor(net.minecraft.server.world.ServerWorld world, List ((ChunkRegion) (Object) this).setBlockState(pos, (net.minecraft.block.BlockState) data, physics ? 3 : 1042); if(physics && ((net.minecraft.block.BlockState) data).getBlock() instanceof FluidBlock) { fluidTickScheduler.scheduleTick( - OrderedTick.create(((FluidBlock) ((net.minecraft.block.BlockState) data).getBlock()).getFluidState( + OrderedTick.create((((FluidBlockInvoker) ((net.minecraft.block.BlockState) data).getBlock())).invokeGetFluidState( (net.minecraft.block.BlockState) data).getFluid(), pos)); } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/invoke/FluidBlockInvoker.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/invoke/FluidBlockInvoker.java new file mode 100644 index 0000000000..620d03ec16 --- /dev/null +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/invoke/FluidBlockInvoker.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.mod.mixin.invoke; + +import net.minecraft.block.BlockState; +import net.minecraft.block.FluidBlock; +import net.minecraft.fluid.FluidState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + + +@Mixin(FluidBlock.class) +public interface FluidBlockInvoker { + @Invoker("getFluidState") + FluidState invokeGetFluidState(BlockState state); +} diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java index 48ea985192..680c1833c8 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/lifecycle/DataPackContentsMixin.java @@ -3,9 +3,12 @@ import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.ReloadableRegistries; import net.minecraft.server.DataPackContents; import net.minecraft.world.biome.Biome; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -16,11 +19,16 @@ @Mixin(DataPackContents.class) public class DataPackContentsMixin { + @Shadow + @Final + private ReloadableRegistries.Lookup reloadableRegistries; + /* * #refresh populates all tags in the registries */ - @Inject(method = "refresh(Lnet/minecraft/registry/DynamicRegistryManager;)V", at = @At("RETURN")) - private void injectReload(DynamicRegistryManager dynamicRegistryManager, CallbackInfo ci) { + @Inject(method = "refresh()V", at = @At("RETURN")) + private void injectReload(CallbackInfo ci) { + DynamicRegistryManager.Immutable dynamicRegistryManager = this.reloadableRegistries.getRegistryManager(); TagUtil.registerWorldPresetTags(dynamicRegistryManager.get(RegistryKeys.WORLD_PRESET)); Registry biomeRegistry = dynamicRegistryManager.get(RegistryKeys.BIOME); diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java index 1c86273644..32c19a4056 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/PresetUtil.java @@ -45,8 +45,9 @@ public static Pair createDefault(ConfigPack pack, ModPl .orElseThrow(); - Identifier generatorID = Identifier.of("terra", pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase( - Locale.ROOT)); + Identifier generatorID = Identifier.tryParse( + "terra:" + pack.getID().toLowerCase(Locale.ROOT) + "/" + pack.getNamespace().toLowerCase( + Locale.ROOT)); PRESETS.add(generatorID); diff --git a/platforms/mixin-common/src/main/resources/terra.accesswidener b/platforms/mixin-common/src/main/resources/terra.accesswidener index d638bbf457..46f1b986e5 100644 --- a/platforms/mixin-common/src/main/resources/terra.accesswidener +++ b/platforms/mixin-common/src/main/resources/terra.accesswidener @@ -1,3 +1,4 @@ accessWidener v1 named accessible class net/minecraft/world/biome/Biome$Weather accessible class net/minecraft/world/gen/WorldPresets$Registrar +accessible class net/minecraft/registry/RegistryLoader$Loader \ No newline at end of file diff --git a/platforms/mixin-common/src/main/resources/terra.common.mixins.json b/platforms/mixin-common/src/main/resources/terra.common.mixins.json index d4402241c5..e25cb7da45 100644 --- a/platforms/mixin-common/src/main/resources/terra.common.mixins.json +++ b/platforms/mixin-common/src/main/resources/terra.common.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.dfsek.terra.mod.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "access.BiomeAccessor", "access.MobSpawnerLogicAccessor", @@ -36,6 +36,7 @@ "implementations.terra.inventory.meta.ItemStackMetaMixin", "implementations.terra.world.ChunkRegionMixin", "implementations.terra.world.ServerWorldMixin", + "invoke.FluidBlockInvoker", "lifecycle.DataPackContentsMixin" ], "client": [ diff --git a/platforms/mixin-lifecycle/build.gradle.kts b/platforms/mixin-lifecycle/build.gradle.kts index 490cdf687a..b7d209b7ff 100644 --- a/platforms/mixin-lifecycle/build.gradle.kts +++ b/platforms/mixin-lifecycle/build.gradle.kts @@ -1,7 +1,6 @@ plugins { id("dev.architectury.loom") version Versions.Mod.architecuryLoom id("architectury-plugin") version Versions.Mod.architecturyPlugin - id("io.github.juuxel.loom-vineflower") version Versions.Mod.loomVineflower } dependencies { @@ -16,7 +15,7 @@ dependencies { minecraft("com.mojang:minecraft:${Versions.Mod.minecraft}") mappings("net.fabricmc:yarn:${Versions.Mod.yarn}:v2") - modImplementation("cloud.commandframework", "cloud-fabric", Versions.Libraries.cloud) { + modImplementation("org.incendo", "cloud-fabric", Versions.Libraries.cloudFabric) { exclude("net.fabricmc") exclude("net.fabricmc.fabric-api") } @@ -31,10 +30,6 @@ loom { } tasks { - compileJava { - options.release.set(17) - } - remapJar { inputFile.set(shadowJar.get().archiveFile) } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecycleEntryPoint.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecycleEntryPoint.java index f20038e5ef..48dc882498 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecycleEntryPoint.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecycleEntryPoint.java @@ -1,14 +1,15 @@ package com.dfsek.terra.lifecycle; -import cloud.commandframework.execution.CommandExecutionCoordinator; -import cloud.commandframework.fabric.FabricServerCommandManager; +import com.dfsek.terra.api.command.CommandSender; +import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent; + import net.minecraft.server.command.ServerCommandSource; +import org.incendo.cloud.SenderMapper; +import org.incendo.cloud.execution.ExecutionCoordinator; +import org.incendo.cloud.fabric.FabricServerCommandManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.dfsek.terra.api.command.CommandSender; -import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent; - public final class LifecycleEntryPoint { private static final Logger logger = LoggerFactory.getLogger(LifecycleEntryPoint.class); @@ -17,9 +18,10 @@ public static void initialize(String modName, LifecyclePlatform platform) { logger.info("Initializing Terra {} mod...", modName); FabricServerCommandManager manager = new FabricServerCommandManager<>( - CommandExecutionCoordinator.simpleCoordinator(), - serverCommandSource -> (CommandSender) serverCommandSource, - commandSender -> (ServerCommandSource) commandSender + ExecutionCoordinator.simpleCoordinator(), + SenderMapper.create( + serverCommandSource -> (CommandSender) serverCommandSource, + commandSender -> (ServerCommandSource) commandSender) ); diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java index be845eb191..3918423117 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/LifecyclePlatform.java @@ -4,6 +4,7 @@ import ca.solostudios.strata.parser.tokenizer.ParseException; import ca.solostudios.strata.version.Version; import net.minecraft.MinecraftVersion; +import net.minecraft.enchantment.Enchantment; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKeys; import net.minecraft.server.MinecraftServer; @@ -34,6 +35,7 @@ public abstract class LifecyclePlatform extends ModPlatform { private static final AtomicReference> DIMENSIONS = new AtomicReference<>(); private static final AtomicReference> SETTINGS = new AtomicReference<>(); private static final AtomicReference> NOISE = new AtomicReference<>(); + private static final AtomicReference> ENCHANTMENT = new AtomicReference<>(); private static MinecraftServer server; public LifecyclePlatform() { @@ -44,11 +46,13 @@ public LifecyclePlatform() { public static void setRegistries(Registry biomeRegistry, Registry dimensionTypeRegistry, Registry chunkGeneratorSettingsRegistry, - Registry multiNoiseBiomeSourceParameterListRegistry) { + Registry multiNoiseBiomeSourceParameterListRegistry, + Registry enchantmentRegistry) { BIOMES.set(biomeRegistry); DIMENSIONS.set(dimensionTypeRegistry); SETTINGS.set(chunkGeneratorSettingsRegistry); NOISE.set(multiNoiseBiomeSourceParameterListRegistry); + ENCHANTMENT.set(enchantmentRegistry); } @Override @@ -69,7 +73,7 @@ public boolean reload() { if(server != null) { BiomeUtil.registerBiomes(server.getRegistryManager().get(RegistryKeys.BIOME)); - server.reloadResources(server.getDataPackManager().getNames()).exceptionally(throwable -> { + server.reloadResources(server.getDataPackManager().getEnabledIds()).exceptionally(throwable -> { LOGGER.warn("Failed to execute reload", throwable); return null; }).join(); @@ -141,5 +145,10 @@ public Registry multiNoiseBiomeSourceParamet return NOISE.get(); } + @Override + public Registry enchantmentRegistry() { + return ENCHANTMENT.get(); + } + protected abstract Collection getPlatformMods(); } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/MinecraftServerMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/MinecraftServerMixin.java index 25ac340d01..0f04c0963c 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/MinecraftServerMixin.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/MinecraftServerMixin.java @@ -16,6 +16,8 @@ import com.dfsek.terra.lifecycle.LifecyclePlatform; +import static com.dfsek.terra.lifecycle.util.LifecycleUtil.initialized; + @Mixin(MinecraftServer.class) public class MinecraftServerMixin { @@ -29,4 +31,9 @@ private void injectConstructor(Thread serverThread, LevelStorage.Session session WorldGenerationProgressListenerFactory worldGenerationProgressListenerFactory, CallbackInfo ci) { LifecyclePlatform.setServer((MinecraftServer) (Object) this); } + + @Inject(method = "shutdown()V", at = @At("RETURN")) + private void injectShutdown(CallbackInfo ci) { + initialized = false; + } } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java index 052598ac25..739c084f37 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/RegistryLoaderMixin.java @@ -1,11 +1,13 @@ package com.dfsek.terra.lifecycle.mixin.lifecycle; -import com.mojang.datafixers.util.Pair; +import net.minecraft.enchantment.Enchantment; import net.minecraft.registry.MutableRegistry; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.RegistryLoader; +import net.minecraft.registry.RegistryLoader.Loader; +import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.source.MultiNoiseBiomeSourceParameterList; import net.minecraft.world.dimension.DimensionType; import net.minecraft.world.gen.WorldPreset; @@ -14,6 +16,7 @@ import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @@ -25,48 +28,50 @@ import com.dfsek.terra.lifecycle.util.LifecycleUtil; import com.dfsek.terra.lifecycle.util.RegistryHack; +import static com.dfsek.terra.lifecycle.util.LifecycleUtil.initialized; + @Mixin(RegistryLoader.class) public class RegistryLoaderMixin { + @Shadow @Final private static Logger LOGGER; @Redirect( - method = "load(Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/registry/DynamicRegistryManager;Ljava/util/List;)" + - "Lnet/minecraft/registry/DynamicRegistryManager$Immutable;", + method = "load(Lnet/minecraft/registry/RegistryLoader$RegistryLoadable;Lnet/minecraft/registry/DynamicRegistryManager;" + + "Ljava/util/List;)Lnet/minecraft/registry/DynamicRegistryManager$Immutable;", at = @At( value = "INVOKE", target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V", ordinal = 1 // we want right after the first forEach ) ) - private static void grabManager(List, Object>> instance, Consumer, Object>> consumer) { - instance.forEach(mutableRegistryObjectPair -> LOGGER.debug("{}: {} entries", - mutableRegistryObjectPair.getFirst().toString(), - mutableRegistryObjectPair.getFirst().size()) - ); - extractRegistry(instance, RegistryKeys.BIOME).ifPresent( - biomes -> { // this redirect triggers twice, second time only with dimension registry. don't try extraction second time - MutableRegistry dimensionTypes = extractRegistry(instance, RegistryKeys.DIMENSION_TYPE).orElseThrow(); - MutableRegistry worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow(); - MutableRegistry chunkGeneratorSettings = extractRegistry(instance, - RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow(); - MutableRegistry multiNoiseBiomeSourceParameterLists = extractRegistry(instance, - RegistryKeys.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST).orElseThrow(); + private static void grabManager(List> instance, Consumer> consumer) { + if(!initialized) { + MutableRegistry biomes = extractRegistry(instance, RegistryKeys.BIOME).orElseThrow(); + MutableRegistry dimensionTypes = extractRegistry(instance, RegistryKeys.DIMENSION_TYPE).orElseThrow(); + MutableRegistry worldPresets = extractRegistry(instance, RegistryKeys.WORLD_PRESET).orElseThrow(); + MutableRegistry chunkGeneratorSettings = extractRegistry(instance, + RegistryKeys.CHUNK_GENERATOR_SETTINGS).orElseThrow(); + MutableRegistry multiNoiseBiomeSourceParameterLists = extractRegistry(instance, + RegistryKeys.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST).orElseThrow(); + MutableRegistry enchantments = extractRegistry(instance, RegistryKeys.ENCHANTMENT).orElseThrow(); - LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings, multiNoiseBiomeSourceParameterLists); - LifecycleUtil.initialize(biomes, worldPresets); - }); + LifecyclePlatform.setRegistries(biomes, dimensionTypes, chunkGeneratorSettings, multiNoiseBiomeSourceParameterLists, + enchantments); + LifecycleUtil.initialize(biomes, worldPresets); + initialized = true; + } instance.forEach(consumer); } + @Unique @SuppressWarnings("unchecked") - private static Optional> extractRegistry(List, Object>> instance, + private static Optional> extractRegistry(List> instance, RegistryKey> key) { List> matches = instance - .stream() - .map(Pair::getFirst) + .stream().map(RegistryLoader.Loader::registry) .filter(r -> r.getKey().equals(key)) .toList(); if(matches.size() > 1) { @@ -74,7 +79,7 @@ private static Optional> extractRegistry(List registry = (MutableRegistry) matches.get(0); + MutableRegistry registry = (MutableRegistry) matches.getFirst(); ((RegistryHack) registry).terra_bind(); return Optional.of(registry); } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java index 6f373130fe..89490ef415 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/mixin/lifecycle/SaveLoadingMixin.java @@ -13,18 +13,18 @@ @Mixin(SaveLoading.class) public class SaveLoadingMixin { @ModifyArg( - method = "method_42097(Lnet/minecraft/registry/DynamicRegistryManager$Immutable;" + - "Lnet/minecraft/server/SaveLoading$SaveApplierFactory;Lnet/minecraft/resource/LifecycledResourceManager;" + - "Lnet/minecraft/registry/CombinedDynamicRegistries;Lnet/minecraft/server/SaveLoading$LoadContext;" + - "Lnet/minecraft/server/DataPackContents;)Ljava/lang/Object;", + method = "load(Lnet/minecraft/server/SaveLoading$ServerConfig;Lnet/minecraft/server/SaveLoading$LoadContextSupplier;" + + "Lnet/minecraft/server/SaveLoading$SaveApplierFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)" + + "Ljava/util/concurrent/CompletableFuture;", at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/DataPackContents;refresh(Lnet/minecraft/registry/DynamicRegistryManager;)V" - ), - index = 0 + target = "Lnet/minecraft/registry/RegistryLoader;loadFromResource(Lnet/minecraft/resource/ResourceManager;" + + "Lnet/minecraft/registry/DynamicRegistryManager;Ljava/util/List;)" + + "Lnet/minecraft/registry/DynamicRegistryManager$Immutable;"), + index = 1 ) - private static DynamicRegistryManager grabManager(DynamicRegistryManager in) { - MinecraftUtil.registerFlora(in.get(RegistryKeys.BIOME)); - return in; + private static DynamicRegistryManager grabManager(DynamicRegistryManager registryManager) { + MinecraftUtil.registerFlora(registryManager.get(RegistryKeys.BIOME)); + return registryManager; } } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java index 5d5ab11c08..b32e129358 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/BiomeUtil.java @@ -58,7 +58,7 @@ private static void registerBiome(Biome biome, ConfigPack pack, net.minecraft.world.biome.Biome minecraftBiome = MinecraftUtil.createBiome(biome, Objects.requireNonNull(registry.get(vanilla)), vanillaBiomeProperties); - Identifier identifier = new Identifier("terra", MinecraftUtil.createBiomeID(pack, id)); + Identifier identifier = Identifier.of("terra", MinecraftUtil.createBiomeID(pack, id)); if(registry.containsId(identifier)) { ((ProtoPlatformBiome) biome.getPlatformBiome()).setDelegate(MinecraftUtil.getEntry(registry, identifier) diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java index a251bedbd1..9ba81f8642 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/LifecycleUtil.java @@ -12,6 +12,8 @@ public final class LifecycleUtil { + public static boolean initialized = false; + private LifecycleUtil() { } diff --git a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java index 03f0639c7c..69bc2ce21a 100644 --- a/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java +++ b/platforms/mixin-lifecycle/src/main/java/com/dfsek/terra/lifecycle/util/RegistryUtil.java @@ -13,7 +13,7 @@ private RegistryUtil() { } public static void register() { - Registry.register(Registries.CHUNK_GENERATOR, new Identifier("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER); - Registry.register(Registries.BIOME_SOURCE, new Identifier("terra:terra"), Codecs.TERRA_BIOME_SOURCE); + Registry.register(Registries.CHUNK_GENERATOR, Identifier.of("terra:terra"), Codecs.MINECRAFT_CHUNK_GENERATOR_WRAPPER); + Registry.register(Registries.BIOME_SOURCE, Identifier.of("terra:terra"), Codecs.TERRA_BIOME_SOURCE); } } diff --git a/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json b/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json index 33695db0eb..2e4708bd49 100644 --- a/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json +++ b/platforms/mixin-lifecycle/src/main/resources/terra.lifecycle.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.dfsek.terra.lifecycle.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ "NoiseConfigMixin", "RegistryEntryReferenceInvoker", diff --git a/platforms/quilt/src/main/resources/terra.quilt.mixins.json b/platforms/quilt/src/main/resources/terra.quilt.mixins.json index 91f51b3445..84ca8264ae 100644 --- a/platforms/quilt/src/main/resources/terra.quilt.mixins.json +++ b/platforms/quilt/src/main/resources/terra.quilt.mixins.json @@ -2,7 +2,7 @@ "required": true, "minVersion": "0.8", "package": "com.dfsek.terra.quilt.mixin", - "compatibilityLevel": "JAVA_17", + "compatibilityLevel": "JAVA_21", "mixins": [ ], "client": [ diff --git a/settings.gradle.kts b/settings.gradle.kts index 7a1cdc8a0d..c5bed6f737 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -5,7 +5,7 @@ fun includeImmediateChildren(dir: File, type: String) { dir.walkTopDown().maxDepth(1).forEach { if (!it.isDirectory || !File(it, "build.gradle.kts").exists()) return@forEach val addonDir = it.relativeTo(file(".")).path.replace("/", ":").replace("\\", ":") - println("Including $type directory \"$addonDir\" as subproject.") + logger.info("Including $type directory \"$addonDir\" as subproject.") include(addonDir) } } @@ -39,3 +39,12 @@ pluginManagement { } } } + +// settings.gradle.kts +val isCiServer = System.getenv().containsKey("CI") +// Cache build artifacts, so expensive operations do not need to be re-computed +buildCache { + local { + isEnabled = !isCiServer + } +} \ No newline at end of file