mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f53bff9421 | |||
| 84a6f43106 |
+3
-4
@@ -1,14 +1,13 @@
|
||||
# Global owners, automatically request review when pull request is submitted
|
||||
* @dfsek @solonovamax @duplexsystem @astrsh @justaureus
|
||||
* @dfsek @solonovamax @duplexsystem @Astrashh @justaureus
|
||||
|
||||
# Platforms
|
||||
/platforms/ @dfsek @solonovamax @duplexsystem @justaureus
|
||||
/platforms/bukkit @dfsek @solonovamax @duplexsystem @justaureus @OakLoaf
|
||||
|
||||
# Common
|
||||
/common/ @dfsek @solonovamax @duplexsystem @astrsh
|
||||
/common/ @dfsek @solonovamax @duplexsystem @Astrashh
|
||||
|
||||
# Gradle Stuff
|
||||
/buildSrc/ @dfsek @solonovamax @duplexsystem
|
||||
*.gradle.kts @dfsek @solonovamax @duplexsystem
|
||||
/gradle/ @dfsek @solonovamax @duplexsystem
|
||||
/gradle/ @dfsek @solonovamax @duplexsystem
|
||||
@@ -44,7 +44,6 @@ You must put an x in all the boxes that it applies to. (Like this: [x])
|
||||
<!-- There is an included `.editorconfig` file in the base of the repo. Please use a plugin for your IDE of choice that follows those settings. -->
|
||||
- [ ] I have read the [`CONTRIBUTING.md`](https://github.com/PolyhedralDev/Terra/blob/master/CONTRIBUTING.md)
|
||||
document in the root of the git repository.
|
||||
- [ ] LLM-based tools were not used to create this PR. (ChatGPT, Claude, etc)
|
||||
|
||||
#### Types of changes
|
||||
|
||||
@@ -99,7 +98,7 @@ You must put an x in all the boxes that it applies to. (Like this: [x])
|
||||
- [ ] I am not the original author of this code, but it is in public domain or
|
||||
released under [GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html) or a compatible license.
|
||||
<!--
|
||||
Please provide reliable evidence of this. LLM-generated code does not satisfy this requirement.
|
||||
Please provide reliable evidence of this.
|
||||
NOTE: for compatible licenses, you must make sure to add the included license somewhere in the program, if so required.
|
||||
(And even if it's not required, it's still nice to do it. Also add attribution somewhere.)
|
||||
-->
|
||||
|
||||
@@ -17,16 +17,16 @@ jobs:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v4.7.1
|
||||
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@v3.0.1
|
||||
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
|
||||
name: Build Terra
|
||||
with:
|
||||
# Specifies arguments for Gradle execution
|
||||
@@ -44,4 +44,4 @@ jobs:
|
||||
# Properties are passed as -Pname=value
|
||||
properties: |
|
||||
kotlin.js.compiler=ir
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
+2
-5
@@ -258,9 +258,6 @@ as [GitHub Pull Requests](https://guides.github.com/activities/forking/#making-a
|
||||
see instead** and why.
|
||||
- **Explain why this enhancement would be useful** to most Terra users and isn't
|
||||
something that can or should be implemented as an addon.
|
||||
- **Do not use LLM/"AI" tools to create your pull request.** Your pr should be written
|
||||
by you. Using an LLM to automate small, tedious tasks (regex and other fiddly things like it)
|
||||
is acceptable, but submitting a low-effort, completely LLM-generated PR will result in a ban.
|
||||
|
||||
## Styleguides
|
||||
|
||||
@@ -384,7 +381,7 @@ compatibilities are welcome and encouraged, in the form of addons.**
|
||||
|
||||
### Platform-Agnostic Design
|
||||
|
||||
Terra must, at all times, remain platform-agnostic. This means it must be able
|
||||
Terra must, at all times, remain platform agnostic. This means it must be able
|
||||
to run on theoretically any voxel based platform. Including non-minecraft games
|
||||
like Terasology.
|
||||
|
||||
@@ -394,7 +391,7 @@ it'll be running on.
|
||||
Examples:
|
||||
|
||||
- Don't assume the world height is 256.
|
||||
- Don't assume that a specific block, item, or entity exists. (E.g. don't assume
|
||||
- Don't assume that a specific block, item, or entity exists. (Eg. don't assume
|
||||
there exists a block called `minecraft:grass_block`)
|
||||
|
||||
### Data-Driven
|
||||
|
||||
Vendored
-149
@@ -1,149 +0,0 @@
|
||||
pipeline {
|
||||
agent any
|
||||
|
||||
tools {
|
||||
jdk "Temurin Java 21"
|
||||
}
|
||||
|
||||
triggers {
|
||||
githubPush()
|
||||
}
|
||||
|
||||
environment {
|
||||
DISCORD_WEBHOOK_URL = credentials('polydev-discord-webhook-url')
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checkout') {
|
||||
steps {
|
||||
scmSkip(deleteBuild: true)
|
||||
}
|
||||
}
|
||||
|
||||
stage('Setup Gradle') {
|
||||
steps {
|
||||
sh 'chmod +x gradlew'
|
||||
}
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
steps {
|
||||
withGradle {
|
||||
sh './gradlew build --rerun-tasks -x check'
|
||||
sh './gradlew javadoc'
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
success {
|
||||
archiveArtifacts artifacts: 'platforms/fabric/build/libs/Terra-fabric*.jar,platforms/bukkit/build/libs/Terra-bukkit*-shaded.jar,platforms/allay/build/libs/Terra-allay*.jar,platforms/minestom/build/libs/Terra-minestom*.jar', fingerprint: true, onlyIfSuccessful: true
|
||||
|
||||
javadoc javadocDir: 'common/api/build/docs/javadoc', keepAll: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stage('Tests') {
|
||||
steps {
|
||||
withGradle {
|
||||
sh './gradlew test --rerun-tasks'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stage('Deploy to snapshots repositories') {
|
||||
// when {
|
||||
// allOf {
|
||||
// not { buildingTag() }
|
||||
// not { expression { env.TAG_NAME != null && env.TAG_NAME.matches('v\\d+\\.\\d+\\.\\d+') } }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// steps {
|
||||
// withCredentials([
|
||||
// string(credentialsId: 'maven-signing-key', variable: 'ORG_GRADLE_PROJECT_signingKey'),
|
||||
// string(credentialsId: 'maven-signing-key-password', variable: 'ORG_GRADLE_PROJECT_signingPassword'),
|
||||
// usernamePassword(
|
||||
// credentialsId: 'solo-studios-maven',
|
||||
// passwordVariable: 'ORG_GRADLE_PROJECT_SoloStudiosSnapshotsPassword',
|
||||
// usernameVariable: 'ORG_GRADLE_PROJECT_SoloStudiosSnapshotsUsername'
|
||||
// )
|
||||
// ]) {
|
||||
// withGradle {
|
||||
// sh './gradlew publishAllPublicationsToSoloStudiosSnapshotsRepository'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
stage('Deploy to releases repositories') {
|
||||
// when {
|
||||
// allOf {
|
||||
// buildingTag()
|
||||
// expression { env.TAG_NAME != null && env.TAG_NAME.matches('v\\d+\\.\\d+\\.\\d+') }
|
||||
// }
|
||||
// }
|
||||
|
||||
steps {
|
||||
withCredentials([
|
||||
string(credentialsId: 'maven-signing-key', variable: 'ORG_GRADLE_PROJECT_signingKey'),
|
||||
string(credentialsId: 'maven-signing-key-password', variable: 'ORG_GRADLE_PROJECT_signingPassword'),
|
||||
usernamePassword(
|
||||
credentialsId: 'solo-studios-maven',
|
||||
passwordVariable: 'ORG_GRADLE_PROJECT_SoloStudiosReleasesPassword',
|
||||
usernameVariable: 'ORG_GRADLE_PROJECT_SoloStudiosReleasesUsername'
|
||||
),
|
||||
// TODO: does not yet exist (uncomment once added)
|
||||
// usernamePassword(
|
||||
// credentialsId: 'sonatype-maven-credentials',
|
||||
// passwordVariable: 'ORG_GRADLE_PROJECT_SonatypePassword',
|
||||
// usernameVariable: 'ORG_GRADLE_PROJECT_SonatypeUsername'
|
||||
// ),
|
||||
// usernamePassword(
|
||||
// credentialsId: 'codemc-maven-credentials',
|
||||
// passwordVariable: 'ORG_GRADLE_PROJECT_CodeMCPassword',
|
||||
// usernameVariable: 'ORG_GRADLE_PROJECT_CodeMCUsername'
|
||||
// )
|
||||
]) {
|
||||
withGradle {
|
||||
sh './gradlew publish'
|
||||
//sh './gradlew publishAllPublicationsToSoloStudiosReleasesRepository'
|
||||
// sh './gradlew publishAllPublicationsToSonatypeRepository'
|
||||
// sh './gradlew publishAllPublicationsToCodeMCRepository'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
post {
|
||||
always {
|
||||
discoverReferenceBuild()
|
||||
|
||||
// junit testResults: '**/build/test-results/*/TEST-*.xml'
|
||||
|
||||
recordIssues(
|
||||
aggregatingResults: true,
|
||||
enabledForFailure: true,
|
||||
minimumSeverity: 'ERROR',
|
||||
sourceCodeEncoding: 'UTF-8',
|
||||
checksAnnotationScope: 'ALL',
|
||||
sourceCodeRetention: 'LAST_BUILD',
|
||||
tools: [java(), javaDoc()]
|
||||
)
|
||||
|
||||
discordSend(
|
||||
title: env.JOB_NAME + ' ' + env.BUILD_DISPLAY_NAME,
|
||||
showChangeset: true,
|
||||
enableArtifactsList: true,
|
||||
link: env.BUILD_URL,
|
||||
result: currentBuild.currentResult,
|
||||
customAvatarUrl: 'https://github.com/PolyhedralDev.png',
|
||||
customUsername: 'Solo Studios Jenkins',
|
||||
webhookURL: env.DISCORD_WEBHOOK_URL,
|
||||
)
|
||||
|
||||
cleanWs()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2025 Polyhedral Development
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+3
-4
@@ -1,8 +1,8 @@
|
||||
preRelease(true)
|
||||
|
||||
versionProjects(":common:api", version("7.0.0"))
|
||||
versionProjects(":common:implementation", version("7.0.0"))
|
||||
versionProjects(":platforms", version("7.0.0"))
|
||||
versionProjects(":common:api", version("6.5.0"))
|
||||
versionProjects(":common:implementation", version("6.5.0"))
|
||||
versionProjects(":platforms", version("6.5.0"))
|
||||
|
||||
|
||||
allprojects {
|
||||
@@ -44,7 +44,6 @@ afterEvaluate {
|
||||
configureDistribution()
|
||||
}
|
||||
project(":platforms:bukkit:common").configureDistribution()
|
||||
project(":platforms:minestom:example").configureDistribution()
|
||||
forSubProjects(":common:addons") {
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
|
||||
|
||||
@@ -6,12 +6,6 @@ plugins {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.solo-studios.ca/releases") {
|
||||
name = "Solo Studios"
|
||||
}
|
||||
maven("https://maven.solo-studios.ca/snapshots") {
|
||||
name = "Solo Studios"
|
||||
}
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
@@ -22,11 +16,11 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
//TODO Allow pulling from Versions.kt
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.9")
|
||||
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("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.18")
|
||||
implementation("org.ow2.asm", "asm", "9.9")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.9")
|
||||
implementation("com.dfsek.tectonic", "common", "4.3.1")
|
||||
implementation("org.yaml", "snakeyaml", "2.5")
|
||||
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")
|
||||
}
|
||||
@@ -13,7 +13,6 @@ import org.gradle.kotlin.dsl.getByName
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import org.gradle.language.jvm.tasks.ProcessResources
|
||||
import org.gradle.plugins.ide.idea.model.IdeaModel
|
||||
|
||||
fun Project.configureCompilation() {
|
||||
apply(plugin = "maven-publish")
|
||||
@@ -22,13 +21,6 @@ fun Project.configureCompilation() {
|
||||
apply(plugin = "idea")
|
||||
apply<TectonicDocPlugin>()
|
||||
|
||||
configure<IdeaModel> {
|
||||
module {
|
||||
isDownloadJavadoc = true
|
||||
isDownloadSources = true
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
|
||||
@@ -30,12 +30,6 @@ fun Project.configureDependencies() {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
maven("https://maven.solo-studios.ca/releases") {
|
||||
name = "Solo Studios"
|
||||
}
|
||||
maven("https://maven.solo-studios.ca/snapshots") {
|
||||
name = "Solo Studios"
|
||||
}
|
||||
maven("https://maven.fabricmc.net/") {
|
||||
name = "FabricMC"
|
||||
}
|
||||
@@ -57,14 +51,11 @@ fun Project.configureDependencies() {
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
|
||||
name = "Sonatype Snapshots"
|
||||
}
|
||||
maven("https://repo.onarandombox.com/multiverse-releases") {
|
||||
name = "onarandombox"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter", Versions.Libraries.Internal.junit)
|
||||
"testRuntimeOnly"("org.junit.platform", "junit-platform-launcher")
|
||||
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", Versions.Libraries.Internal.guava)
|
||||
|
||||
@@ -4,11 +4,9 @@ import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.net.URL
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Path
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.BasePluginExtension
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
@@ -21,25 +19,6 @@ import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.createFile
|
||||
import kotlin.io.path.exists
|
||||
|
||||
private fun Project.installAddonsInto(dest: Path) {
|
||||
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
||||
forSubProjects(":common:addons") {
|
||||
val jar = getJarTask()
|
||||
|
||||
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()}")
|
||||
|
||||
if (!addonPath.exists()) {
|
||||
addonPath.parent.createDirectories()
|
||||
addonPath.createFile()
|
||||
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureDistribution() {
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
@@ -47,23 +26,10 @@ fun Project.configureDistribution() {
|
||||
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
||||
group = "terra"
|
||||
doFirst {
|
||||
try {
|
||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||
file("${buildDir}/resources/main/metapacks/").deleteRecursively()
|
||||
val overworldPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/Overworld.zip")
|
||||
val reimagENDPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/ReimagEND/releases/download/" + Versions.Terra.reimagENDConfig + "/ReimagEND.zip")
|
||||
val tartarusPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/Tartarus/releases/download/" + Versions.Terra.tartarusConfig + "/Tartarus.zip")
|
||||
val defaultPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/DefaultMetapack/releases/download/" + Versions.Terra.defaultConfig + "/default.zip")
|
||||
downloadPack(overworldPackUrl, project)
|
||||
downloadPack(reimagENDPackUrl, project)
|
||||
downloadPack(tartarusPackUrl, project)
|
||||
downloadPack(defaultPackUrl, project, true)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||
val defaultPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip")
|
||||
downloadPack(defaultPackUrl, project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,17 +48,25 @@ fun Project.configureDistribution() {
|
||||
doLast {
|
||||
// https://github.com/johnrengelman/shadow/issues/111
|
||||
val dest = tasks.named<ShadowJar>("shadowJar").get().archiveFile.get().path
|
||||
installAddonsInto(dest)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("installAddonsIntoDefaultJar") {
|
||||
group = "terra"
|
||||
dependsOn(compileAddons)
|
||||
|
||||
doLast {
|
||||
val dest = tasks.named<Jar>("jar").get().archiveFile.get().path
|
||||
installAddonsInto(dest)
|
||||
|
||||
|
||||
FileSystems.newFileSystem(dest, mapOf("create" to "false"), null).use { fs ->
|
||||
forSubProjects(":common:addons") {
|
||||
val jar = getJarTask()
|
||||
|
||||
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()}")
|
||||
|
||||
if (!addonPath.exists()) {
|
||||
addonPath.parent.createDirectories()
|
||||
addonPath.createFile()
|
||||
jar.archiveFile.get().asFile.toPath().copyTo(addonPath, overwrite = true)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,13 +81,6 @@ fun Project.configureDistribution() {
|
||||
resources.computeIfAbsent("packs") { ArrayList() }.add(it.name)
|
||||
}
|
||||
|
||||
val metaPacksDir = File("${project.buildDir}/resources/main/metapacks/")
|
||||
|
||||
metaPacksDir.walkTopDown().forEach {
|
||||
if (it.isDirectory || !it.name.endsWith(".zip")) return@forEach
|
||||
resources.computeIfAbsent("metapacks") { ArrayList() }.add(it.name)
|
||||
}
|
||||
|
||||
val langDir = File("${project(":common:implementation").buildDir}/resources/main/lang/")
|
||||
|
||||
langDir.walkTopDown().forEach {
|
||||
@@ -166,6 +133,7 @@ fun Project.configureDistribution() {
|
||||
version = project.version
|
||||
relocate("org.apache.commons", "com.dfsek.terra.lib.commons")
|
||||
relocate("org.objectweb.asm", "com.dfsek.terra.lib.asm")
|
||||
relocate("com.dfsek.paralithic", "com.dfsek.terra.lib.paralithic")
|
||||
relocate("org.json", "com.dfsek.terra.lib.json")
|
||||
relocate("org.yaml", "com.dfsek.terra.lib.yaml")
|
||||
|
||||
@@ -181,10 +149,9 @@ fun Project.configureDistribution() {
|
||||
}
|
||||
}
|
||||
|
||||
fun downloadPack(packUrl: URL, project: Project, metapack: Boolean = false) {
|
||||
fun downloadPack(packUrl: URL, project: Project) {
|
||||
val fileName = packUrl.file.substring(packUrl.file.lastIndexOf("/"))
|
||||
val resourceType = if (metapack) "metapacks" else "packs"
|
||||
val file = File("${project.buildDir}/resources/main/${resourceType}/${fileName}")
|
||||
val file = File("${project.buildDir}/resources/main/packs/${fileName}")
|
||||
file.parentFile.mkdirs()
|
||||
file.outputStream().write(packUrl.readBytes())
|
||||
}
|
||||
|
||||
@@ -16,17 +16,16 @@ fun Project.configurePublishing() {
|
||||
}
|
||||
|
||||
repositories {
|
||||
val mavenUrl = "https://maven.solo-studios.ca/releases/"
|
||||
val mavenUrl = "https://repo.codemc.io/repository/maven-releases/"
|
||||
//val mavenSnapshotUrl = "https://repo.codemc.io/repository/maven-snapshots/"
|
||||
|
||||
maven(mavenUrl) {
|
||||
val SoloStudiosReleasesUsername: String? by project
|
||||
val SoloStudiosReleasesPassword: String? by project
|
||||
|
||||
if (SoloStudiosReleasesUsername != null && SoloStudiosReleasesPassword != null) {
|
||||
val mavenUsername: String? by project
|
||||
val mavenPassword: String? by project
|
||||
if (mavenUsername != null && mavenPassword != null) {
|
||||
credentials {
|
||||
username = SoloStudiosReleasesUsername
|
||||
password = SoloStudiosReleasesPassword
|
||||
username = mavenUsername
|
||||
password = mavenPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,35 @@
|
||||
object Versions {
|
||||
object Terra {
|
||||
const val overworldConfig = "latest"
|
||||
const val reimagENDConfig = "latest"
|
||||
const val tartarusConfig = "latest"
|
||||
const val defaultConfig = "latest"
|
||||
const val overworldConfig = "v1.3.4"
|
||||
}
|
||||
|
||||
object Libraries {
|
||||
const val tectonic = "4.3.1"
|
||||
const val paralithic = "2.0.1"
|
||||
const val tectonic = "4.2.1"
|
||||
const val paralithic = "0.7.1"
|
||||
const val strata = "1.3.2"
|
||||
const val seismic = "2.5.7"
|
||||
|
||||
const val cloud = "2.0.0"
|
||||
const val cloudPaper = "2.0.0-beta.10"
|
||||
const val cloudFabric = "2.0.0-beta.9"
|
||||
|
||||
const val caffeine = "3.2.2"
|
||||
const val caffeine = "3.1.8"
|
||||
|
||||
const val slf4j = "2.0.17"
|
||||
const val slf4j = "2.0.16"
|
||||
|
||||
object Internal {
|
||||
const val shadow = "8.3.9"
|
||||
const val apacheText = "1.14.0"
|
||||
const val apacheIO = "2.20.0"
|
||||
const val guava = "33.5.0-jre"
|
||||
const val asm = "9.9"
|
||||
const val snakeYml = "2.5"
|
||||
const val jetBrainsAnnotations = "26.0.2-1"
|
||||
const val junit = "6.0.0"
|
||||
const val nbt = "6.1"
|
||||
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.134.1+${Mod.minecraft}"
|
||||
const val cloud = "2.0.0-beta.13"
|
||||
const val fabricAPI = "0.104.0+${Mod.minecraft}"
|
||||
}
|
||||
//
|
||||
// object Quilt {
|
||||
@@ -42,16 +38,14 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Mod {
|
||||
const val mixin = "0.16.4+mixin.0.8.7"
|
||||
const val mixinExtras = "0.5.0"
|
||||
const val mixin = "0.15.3+mixin.0.8.7"
|
||||
|
||||
const val minecraft = "1.21.10"
|
||||
const val yarn = "$minecraft+build.1"
|
||||
const val fabricLoader = "0.18.2"
|
||||
const val minecraft = "1.21.1"
|
||||
const val yarn = "$minecraft+build.3"
|
||||
const val fabricLoader = "0.16.5"
|
||||
|
||||
const val architecuryLoom = "1.11.451"
|
||||
const val architecturyPlugin = "3.4.162"
|
||||
|
||||
const val architecuryLoom = "1.7.413"
|
||||
const val architecturyPlugin = "3.4.159"
|
||||
}
|
||||
//
|
||||
// object Forge {
|
||||
@@ -60,20 +54,17 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Bukkit {
|
||||
const val minecraft = "1.21.10"
|
||||
const val nms = "$minecraft-R0.1"
|
||||
const val paperBuild = "$nms-20251012.013929-7"
|
||||
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.3"
|
||||
const val reflectionRemapper = "0.1.1"
|
||||
const val paperDevBundle = paperBuild
|
||||
const val runPaper = "2.3.1"
|
||||
const val paperWeight = "2.0.0-beta.19"
|
||||
const val cloud = "2.0.0-beta.12"
|
||||
const val multiverse = "5.3.0"
|
||||
const val paperWeight = "1.7.2"
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// object Sponge {
|
||||
// const val sponge = "9.0.0-SNAPSHOT"
|
||||
// const val mixin = "0.8.2"
|
||||
@@ -81,21 +72,7 @@ object Versions {
|
||||
// }
|
||||
//
|
||||
object CLI {
|
||||
const val logback = "1.5.19"
|
||||
const val picocli = "4.7.7"
|
||||
const val nbt = "6.1"
|
||||
const val logback = "1.5.8"
|
||||
}
|
||||
|
||||
object Allay {
|
||||
const val api = "0.20.0"
|
||||
const val gson = "2.13.2"
|
||||
|
||||
const val mappings = "366baa6"
|
||||
const val mappingsGenerator = "e957088"
|
||||
|
||||
const val mcmeta = "c976eb3"
|
||||
}
|
||||
|
||||
object Minestom {
|
||||
const val minestom = "2025.10.04-1.21.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2025 Polyhedral Development
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
|
||||
+1
-1
@@ -46,6 +46,6 @@ class BaseBiomeColumn implements Column<Biome> {
|
||||
|
||||
@Override
|
||||
public Biome get(int y) {
|
||||
return biomeProvider.pipeline.extrude(base, x, y, z, seed);
|
||||
return biomeProvider.extrude(base, x, y, z, seed);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -6,33 +6,37 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipeline;
|
||||
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipelineFactory;
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomeExtrusionProvider implements BiomeProvider {
|
||||
public final ExtrusionPipeline pipeline;
|
||||
private final BiomeProvider delegate;
|
||||
private final Set<Biome> biomes;
|
||||
private final List<Extrusion> extrusions;
|
||||
private final int resolution;
|
||||
|
||||
public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) {
|
||||
this.delegate = delegate;
|
||||
this.biomes = delegate.stream().collect(Collectors.toSet());
|
||||
extrusions.forEach(e -> biomes.addAll(e.getBiomes()));
|
||||
|
||||
this.pipeline = ExtrusionPipelineFactory.create(extrusions);
|
||||
|
||||
this.extrusions = extrusions;
|
||||
this.resolution = resolution;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z, long seed) {
|
||||
Biome delegated = delegate.getBiome(x, y, z, seed);
|
||||
return pipeline.extrude(delegated, x, y, z, seed);
|
||||
|
||||
return extrude(delegated, x, y, z, seed);
|
||||
}
|
||||
|
||||
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||
for(Extrusion extrusion : extrusions) {
|
||||
original = extrusion.extrude(original, x, y, z, seed);
|
||||
}
|
||||
return original;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,4 +64,4 @@ public class BiomeExtrusionProvider implements BiomeProvider {
|
||||
public BiomeProvider getDelegate() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,17 +1,17 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.config.extrusions;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.range.Range;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
|
||||
|
||||
public abstract class SamplerExtrusionTemplate implements ObjectTemplate<Extrusion> {
|
||||
@Value("sampler")
|
||||
protected @Meta Sampler sampler;
|
||||
protected @Meta NoiseSampler sampler;
|
||||
|
||||
@Value("range")
|
||||
protected @Meta Range range;
|
||||
|
||||
+12
-30
@@ -1,7 +1,5 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -9,9 +7,9 @@ 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;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.collection.TriStateIntCache;
|
||||
import com.dfsek.terra.api.util.range.Range;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
@@ -19,42 +17,26 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
* Sets biomes at locations based on a sampler.
|
||||
*/
|
||||
public class ReplaceExtrusion implements Extrusion {
|
||||
private final Sampler sampler;
|
||||
private final Range range;
|
||||
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||
private final Predicate<Biome> hasTag;
|
||||
private final TriStateIntCache cache;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public ReplaceExtrusion(Sampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
|
||||
private final Range range;
|
||||
|
||||
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||
|
||||
private final Predicate<Biome> hasTag;
|
||||
|
||||
public ReplaceExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
|
||||
this.sampler = sampler;
|
||||
this.range = range;
|
||||
this.biomes = biomes;
|
||||
this.hasTag = BiomeQueries.has(tag);
|
||||
this.cache = new TriStateIntCache(Biome.INT_ID_COUNTER.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||
int id = original.getIntID();
|
||||
|
||||
long state = cache.get(id);
|
||||
boolean passes;
|
||||
|
||||
if(state == TriStateIntCache.STATE_UNSET) {
|
||||
// Only run the test if unset in cache
|
||||
passes = hasTag.test(original);
|
||||
cache.set(id, passes);
|
||||
} else {
|
||||
// Read the primitive long directly
|
||||
passes = (state == TriStateIntCache.STATE_TRUE);
|
||||
if(hasTag.test(original)) {
|
||||
return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
|
||||
}
|
||||
|
||||
if(passes) {
|
||||
if(range.isInRange(y)) {
|
||||
return biomes.get(sampler, x, y, z, seed).get(original);
|
||||
}
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
|
||||
+4
-5
@@ -1,15 +1,14 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
|
||||
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.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.range.Range;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
@@ -17,13 +16,13 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
* Sets biomes at locations based on a sampler.
|
||||
*/
|
||||
public class SetExtrusion implements Extrusion {
|
||||
private final Sampler sampler;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
private final Range range;
|
||||
|
||||
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||
|
||||
public SetExtrusion(Sampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
|
||||
public SetExtrusion(NoiseSampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes) {
|
||||
this.sampler = sampler;
|
||||
this.range = range;
|
||||
this.biomes = biomes;
|
||||
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.utils;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
public interface ExtrusionPipeline {
|
||||
Biome extrude(Biome original, int x, int y, int z, long seed);
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.utils;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.AALOAD;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ALOAD;
|
||||
import static org.objectweb.asm.Opcodes.ARETURN;
|
||||
import static org.objectweb.asm.Opcodes.GETFIELD;
|
||||
import static org.objectweb.asm.Opcodes.ILOAD;
|
||||
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
|
||||
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
|
||||
import static org.objectweb.asm.Opcodes.LLOAD;
|
||||
import static org.objectweb.asm.Opcodes.PUTFIELD;
|
||||
import static org.objectweb.asm.Opcodes.RETURN;
|
||||
import static org.objectweb.asm.Opcodes.SIPUSH;
|
||||
import static org.objectweb.asm.Opcodes.SWAP;
|
||||
import static org.objectweb.asm.Opcodes.V1_8;
|
||||
|
||||
|
||||
public class ExtrusionPipelineFactory {
|
||||
private static final AtomicInteger ID_COUNTER = new AtomicInteger(0);
|
||||
|
||||
// Type Descriptors
|
||||
private static final String EXTRUSION_TYPE = Type.getInternalName(Extrusion.class);
|
||||
private static final String EXTRUSION_DESC = Type.getDescriptor(Extrusion.class);
|
||||
private static final String BIOME_DESC = Type.getDescriptor(Biome.class);
|
||||
private static final String PIPELINE_INTERFACE = Type.getInternalName(ExtrusionPipeline.class);
|
||||
|
||||
// Method Signature: (Biome, int, int, int, long) -> Biome
|
||||
private static final String EXTRUDE_SIG = "(" + BIOME_DESC + "IIIJ)" + BIOME_DESC;
|
||||
|
||||
public static ExtrusionPipeline create(List<Extrusion> extrusions) {
|
||||
// Optimization: If empty, return identity
|
||||
if(extrusions.isEmpty()) {
|
||||
return (original, x, y, z, seed) -> original;
|
||||
}
|
||||
|
||||
String className = "com/dfsek/terra/addons/biome/extrusion/GeneratedExtrusionPipeline_" + ID_COUNTER.getAndIncrement();
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||
|
||||
// 1. Define Class
|
||||
cw.visit(V1_8, ACC_PUBLIC | ACC_FINAL, className, null, "java/lang/Object", new String[]{ PIPELINE_INTERFACE });
|
||||
|
||||
// 2. Define Fields (e0, e1, e2...)
|
||||
for(int i = 0; i < extrusions.size(); i++) {
|
||||
FieldVisitor fv = cw.visitField(ACC_PRIVATE | ACC_FINAL, "e" + i, EXTRUSION_DESC, null, null);
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
||||
// 3. Generate Constructor(Extrusion[])
|
||||
generateConstructor(cw, className, extrusions.size());
|
||||
|
||||
// 4. Generate extrude() method
|
||||
generateExtrudeMethod(cw, className, extrusions.size());
|
||||
|
||||
cw.visitEnd();
|
||||
|
||||
// 5. Load and Instantiate
|
||||
byte[] bytecode = cw.toByteArray();
|
||||
try {
|
||||
Class<?> generatedClass = new PipelineClassLoader(ExtrusionPipelineFactory.class.getClassLoader())
|
||||
.defineClass(className.replace('/', '.'), bytecode);
|
||||
|
||||
return (ExtrusionPipeline) generatedClass.getConstructor(Extrusion[].class)
|
||||
.newInstance((Object) extrusions.toArray(new Extrusion[0]));
|
||||
} catch(Exception e) {
|
||||
throw new RuntimeException("Failed to generate ExtrusionPipeline", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateConstructor(ClassWriter cw, String className, int count) {
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "([L" + EXTRUSION_TYPE + ";)V", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
// super()
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||
|
||||
// Assign array elements to fields
|
||||
for(int i = 0; i < count; i++) {
|
||||
mv.visitVarInsn(ALOAD, 0); // Load this
|
||||
mv.visitVarInsn(ALOAD, 1); // Load array argument
|
||||
mv.visitIntInsn(SIPUSH, i); // Load index
|
||||
mv.visitInsn(AALOAD); // Load array[i]
|
||||
mv.visitFieldInsn(PUTFIELD, className, "e" + i, EXTRUSION_DESC);
|
||||
}
|
||||
|
||||
mv.visitInsn(RETURN);
|
||||
mv.visitMaxs(0, 0); // Computed automatically
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
private static void generateExtrudeMethod(ClassWriter cw, String className, int count) {
|
||||
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "extrude", EXTRUDE_SIG, null, null);
|
||||
mv.visitCode();
|
||||
|
||||
// Helper var indices:
|
||||
// 0: this
|
||||
// 1: Biome original (We will update this or chain it on stack)
|
||||
// 2: int x
|
||||
// 3: int y
|
||||
// 4: int z
|
||||
// 5: long seed
|
||||
|
||||
mv.visitVarInsn(ALOAD, 1); // Load 'original' Biome onto stack initially
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
// Stack contains: [CurrentBiome]
|
||||
|
||||
mv.visitVarInsn(ALOAD, 0); // Load 'this'
|
||||
mv.visitFieldInsn(GETFIELD, className, "e" + i, EXTRUSION_DESC); // Load Extrusion field
|
||||
|
||||
// Stack: [CurrentBiome, Extrusion]
|
||||
// We need: [Extrusion, CurrentBiome, x, y, z, seed]
|
||||
|
||||
mv.visitInsn(SWAP); // Swap to get [Extrusion, CurrentBiome]
|
||||
|
||||
mv.visitVarInsn(ILOAD, 2); // x
|
||||
mv.visitVarInsn(ILOAD, 3); // y
|
||||
mv.visitVarInsn(ILOAD, 4); // z
|
||||
mv.visitVarInsn(LLOAD, 5); // seed
|
||||
|
||||
// Invoke Extrusion.extrude(Biome, x, y, z, seed)
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, EXTRUSION_TYPE, "extrude", EXTRUDE_SIG, true);
|
||||
|
||||
// Stack now contains: [NewBiome]
|
||||
// Loop continues using this result as input for the next one
|
||||
}
|
||||
|
||||
mv.visitInsn(ARETURN); // Return the final Biome
|
||||
mv.visitMaxs(0, 0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
// Custom ClassLoader to inject the bytes
|
||||
private static class PipelineClassLoader extends ClassLoader {
|
||||
public PipelineClassLoader(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> defineClass(String name, byte[] b) {
|
||||
return defineClass(name, b, 0, b.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,5 @@
|
||||
# biome-provider-image-v2
|
||||
|
||||
Implements and registers the `IMAGE` biome provider, which
|
||||
utilizes various config types provided by the `library-image` addon to
|
||||
distribute biomes based on images.
|
||||
@@ -0,0 +1,8 @@
|
||||
version = version("1.0.1")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
compileOnlyApi(project(":common:addons:library-image"))
|
||||
|
||||
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.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;
|
||||
|
||||
|
||||
public class ImageBiomeProvider implements BiomeProvider {
|
||||
private final int resolution;
|
||||
|
||||
private final ColorConverter<Biome> colorConverter;
|
||||
|
||||
private final ColorSampler colorSampler;
|
||||
|
||||
public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) {
|
||||
this.resolution = resolution;
|
||||
this.colorConverter = colorConverter;
|
||||
this.colorSampler = colorSampler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z, long seed) {
|
||||
return getBiome(x, z);
|
||||
}
|
||||
|
||||
public Biome getBiome(int x, int z) {
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
return colorConverter.apply(colorSampler.apply(x, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||
return Optional.of(getBiome(x, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Biome> getBiomes() {
|
||||
return colorConverter.getEntries();
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.biome.image.v2;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.dfsek.terra.addons.biome.image.v2.config.ImageProviderTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.v2.config.converter.ClosestBiomeColorConverterTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.v2.config.converter.ExactBiomeColorConverterTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.v2.config.converter.mapping.DefinedBiomeColorMappingTemplate;
|
||||
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||
import com.dfsek.terra.addons.image.converter.mapping.BiomeDefinedColorMapping;
|
||||
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||
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.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.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class ImageBiomeProviderAddon implements AddonInitializer {
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<Biome>>>> BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
@Inject
|
||||
private Platform platform;
|
||||
|
||||
@Inject
|
||||
private BaseAddon addon;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.priority(501)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||
PROVIDER_REGISTRY_KEY);
|
||||
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
|
||||
event.getPack().getOrCreateRegistry(
|
||||
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
|
||||
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
|
||||
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
|
||||
event.getPack().getOrCreateRegistry(
|
||||
BIOME_COLOR_MAPPING_REGISTRY_KEY);
|
||||
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
|
||||
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
|
||||
b -> b));
|
||||
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.image.config;
|
||||
package com.dfsek.terra.addons.biome.image.v2.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.image.ImageBiomeProvider;
|
||||
import com.dfsek.terra.addons.biome.image.v2.ImageBiomeProvider;
|
||||
import com.dfsek.terra.addons.image.colorsampler.ColorSampler;
|
||||
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.image.config.converter;
|
||||
package com.dfsek.terra.addons.biome.image.v2.config.converter;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.image.config.converter;
|
||||
package com.dfsek.terra.addons.biome.image.v2.config.converter;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.image.config.converter.mapping;
|
||||
package com.dfsek.terra.addons.biome.image.v2.config.converter.mapping;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
@@ -0,0 +1,14 @@
|
||||
schema-version: 1
|
||||
contributors:
|
||||
- Terra contributors
|
||||
id: biome-provider-image-v2
|
||||
version: @VERSION@
|
||||
entrypoints:
|
||||
- "com.dfsek.terra.addons.biome.image.v2.ImageBiomeProviderAddon"
|
||||
website:
|
||||
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||
source: https://github.com/PolyhedralDev/Terra
|
||||
docs: https://terra.polydev.org
|
||||
license: MIT License
|
||||
depends:
|
||||
library-image: "1.+"
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2025 Polyhedral Development
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# biome-provider-image-v2
|
||||
# biome-provider-image
|
||||
|
||||
Implements and registers the `IMAGE` biome provider, which
|
||||
utilizes various config types provided by the `library-image` addon to
|
||||
distribute biomes based on images.
|
||||
Implements and registers the `IMAGE` biome provider, a biome provider which
|
||||
generates biomes from an image, using the `color` attribute of biomes.
|
||||
|
||||
This addon registers the provider type, and all associated config options.
|
||||
@@ -1,8 +1,7 @@
|
||||
version = version("2.0.0")
|
||||
version = version("1.0.1")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
compileOnlyApi(project(":common:addons:library-image"))
|
||||
|
||||
|
||||
}
|
||||
|
||||
+45
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
@@ -7,25 +7,32 @@
|
||||
|
||||
package com.dfsek.terra.addons.biome.image;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
public class ImageBiomeProvider implements BiomeProvider {
|
||||
private final Map<Color, Biome> colorBiomeMap = new HashMap<>();
|
||||
private final BufferedImage image;
|
||||
private final int resolution;
|
||||
private final Align align;
|
||||
|
||||
private final ColorConverter<Biome> colorConverter;
|
||||
|
||||
private final ColorSampler colorSampler;
|
||||
|
||||
public ImageBiomeProvider(ColorConverter<Biome> colorConverter, ColorSampler colorSampler, int resolution) {
|
||||
public ImageBiomeProvider(Set<Biome> registry, BufferedImage image, int resolution, Align align) {
|
||||
this.image = image;
|
||||
this.resolution = resolution;
|
||||
this.colorConverter = colorConverter;
|
||||
this.colorSampler = colorSampler;
|
||||
this.align = align;
|
||||
registry.forEach(biome -> colorBiomeMap.put(new Color(biome.getColor()), biome));
|
||||
}
|
||||
|
||||
private static int distance(Color a, Color b) {
|
||||
return Math.abs(a.getRed() - b.getRed()) + Math.abs(a.getGreen() - b.getGreen()) + Math.abs(a.getBlue() - b.getBlue());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,7 +43,15 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
public Biome getBiome(int x, int z) {
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
return colorConverter.apply(colorSampler.apply(x, z));
|
||||
Color color = align.getColor(image, x, z);
|
||||
return colorBiomeMap.get(colorBiomeMap.keySet()
|
||||
.stream()
|
||||
.reduce(colorBiomeMap.keySet().stream().findAny().orElseThrow(IllegalStateException::new),
|
||||
(running, element) -> {
|
||||
int d1 = distance(color, running);
|
||||
int d2 = distance(color, element);
|
||||
return d1 < d2 ? running : element;
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,6 +61,24 @@ public class ImageBiomeProvider implements BiomeProvider {
|
||||
|
||||
@Override
|
||||
public Iterable<Biome> getBiomes() {
|
||||
return colorConverter.getEntries();
|
||||
return colorBiomeMap.values();
|
||||
}
|
||||
|
||||
public enum Align {
|
||||
CENTER {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(Math.floorMod(x - image.getWidth() / 2, image.getWidth()),
|
||||
Math.floorMod(z - image.getHeight() / 2, image.getHeight())));
|
||||
}
|
||||
},
|
||||
NONE {
|
||||
@Override
|
||||
public Color getColor(BufferedImage image, int x, int z) {
|
||||
return new Color(image.getRGB(Math.floorMod(x, image.getWidth()), Math.floorMod(z, image.getHeight())));
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Color getColor(BufferedImage image, int x, int z);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
@@ -8,16 +8,11 @@
|
||||
package com.dfsek.terra.addons.biome.image;
|
||||
|
||||
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.biome.image.config.ImageProviderTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.config.converter.ClosestBiomeColorConverterTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.config.converter.ExactBiomeColorConverterTemplate;
|
||||
import com.dfsek.terra.addons.biome.image.config.converter.mapping.DefinedBiomeColorMappingTemplate;
|
||||
import com.dfsek.terra.addons.image.converter.ColorConverter;
|
||||
import com.dfsek.terra.addons.image.converter.mapping.BiomeDefinedColorMapping;
|
||||
import com.dfsek.terra.addons.image.converter.mapping.ColorMapping;
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
@@ -31,15 +26,10 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class ImageBiomeProviderAddon implements AddonInitializer {
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<ColorConverter<Biome>>>> BIOME_COLOR_CONVERTER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<ColorMapping<Biome>>>> BIOME_COLOR_MAPPING_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ImageBiomeProviderAddon.class);
|
||||
@Inject
|
||||
private Platform platform;
|
||||
|
||||
@@ -51,28 +41,16 @@ public class ImageBiomeProviderAddon implements AddonInitializer {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.priority(501)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||
PROVIDER_REGISTRY_KEY);
|
||||
providerRegistry.register(addon.key("IMAGE"), ImageProviderTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<ColorConverter<Biome>>>> biomeColorConverterRegistry =
|
||||
event.getPack().getOrCreateRegistry(
|
||||
BIOME_COLOR_CONVERTER_REGISTRY_KEY);
|
||||
biomeColorConverterRegistry.register(addon.key("EXACT"), ExactBiomeColorConverterTemplate::new);
|
||||
biomeColorConverterRegistry.register(addon.key("CLOSEST"), ClosestBiomeColorConverterTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<ColorMapping<Biome>>>> biomeColorMappingRegistry =
|
||||
event.getPack().getOrCreateRegistry(
|
||||
BIOME_COLOR_MAPPING_REGISTRY_KEY);
|
||||
biomeColorMappingRegistry.register(addon.key("USE_BIOME_COLORS"),
|
||||
() -> () -> new BiomeDefinedColorMapping<>(event.getPack().getRegistry(Biome.class),
|
||||
b -> b));
|
||||
biomeColorMappingRegistry.register(addon.key("MAP"), DefinedBiomeColorMappingTemplate::new);
|
||||
providerRegistry.register(addon.key("IMAGE"),
|
||||
() -> new ImageProviderTemplate(event.getPack().getRegistry(Biome.class)));
|
||||
})
|
||||
.failThrough();
|
||||
if(platform.getTerraConfig().isDebugLog())
|
||||
logger.warn(
|
||||
"The biome-provider-image addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the " +
|
||||
"biome-provider-image-v2 addon for future pack development instead.");
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.biome.image;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class ImageProviderTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
private final Registry<Biome> biomes;
|
||||
@Value("resolution")
|
||||
@Default
|
||||
@Description("Sets the resolution at which to sample the image.")
|
||||
private int resolution = 1;
|
||||
@Value("image.name")
|
||||
@Description("Sets the location of the image on the filesystem, relative to the pack root.")
|
||||
private BufferedImage image;
|
||||
@Value("image.align")
|
||||
@Description("Sets the alignment style to use for the image.")
|
||||
private ImageBiomeProvider.Align align;
|
||||
|
||||
public ImageProviderTemplate(Registry<Biome> set) {
|
||||
this.biomes = set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeProvider get() {
|
||||
return new ImageBiomeProvider(new HashSet<>(biomes.entries()), image, resolution, align);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,4 @@ website:
|
||||
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||
source: https://github.com/PolyhedralDev/Terra
|
||||
docs: https://terra.polydev.org
|
||||
license: MIT License
|
||||
depends:
|
||||
library-image: "1.+"
|
||||
license: MIT License
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,12 @@
|
||||
# biome-provider-pipeline-2
|
||||
|
||||
The second version of the Biome Pipeline, a procedural biome provider that uses a series
|
||||
of "stages" to apply "mutations" to a 2D grid of biomes.
|
||||
|
||||
Version 2 is a re-implementation of the original addon with the primary goal of providing
|
||||
consistent scaling for noise relative to the world
|
||||
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been
|
||||
included as a separate addon to maintain parity with packs utilizing the first version.
|
||||
|
||||
This addon registers the `PIPELINE` biome provider type, and all associated
|
||||
configurations.
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
version = version("1.0.0")
|
||||
version = version("1.0.1")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.biome.pipeline.v2;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.PipelineBiomeLoader;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.source.SamplerSourceTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderListStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.BorderStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceListStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.ReplaceStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator.SmoothStageTemplate;
|
||||
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.pack.ConfigPackPostLoadEvent;
|
||||
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.registry.Registry;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomePipelineAddon implements AddonInitializer {
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<Source>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
@Inject
|
||||
private Platform platform;
|
||||
|
||||
@Inject
|
||||
private BaseAddon addon;
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeProvider>>> providerRegistry = event.getPack().getOrCreateRegistry(
|
||||
PROVIDER_REGISTRY_KEY);
|
||||
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
|
||||
SOURCE_REGISTRY_KEY);
|
||||
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
|
||||
STAGE_REGISTRY_KEY);
|
||||
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
|
||||
stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigPackPostLoadEvent.class)
|
||||
.then(event -> {
|
||||
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||
event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry));
|
||||
});
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.util.function.IntIntObjConsumer;
|
||||
import com.dfsek.terra.api.util.function.IntObjConsumer;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomePipelineColumn implements Column<Biome> {
|
||||
private final int min;
|
||||
private final int max;
|
||||
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final Biome biome;
|
||||
|
||||
protected BiomePipelineColumn(BiomeProvider biomeProvider, int min, int max, int x, int z, long seed) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.biome = biomeProvider.getBiome(x, 0, z, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinY() {
|
||||
return min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxY() {
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome get(int y) {
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forRanges(int resolution, IntIntObjConsumer<Biome> consumer) {
|
||||
consumer.accept(min, max, biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<Biome> consumer) {
|
||||
for(int y = min; y < max; y++) {
|
||||
consumer.accept(biome);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(IntObjConsumer<Biome> consumer) {
|
||||
for(int y = min; y < max; y++) {
|
||||
consumer.accept(y, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-20
@@ -1,13 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 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.biome.pipeline.v2;
|
||||
|
||||
package com.dfsek.terra.addons.biome.pipeline;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
@@ -17,27 +9,28 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class PipelineBiomeProvider implements BiomeProvider {
|
||||
|
||||
private final LoadingCache<SeededVector2Key, BiomeChunk> biomeChunkCache;
|
||||
private final LoadingCache<SeededVector, BiomeChunk> biomeChunkCache;
|
||||
private final int chunkSize;
|
||||
private final int resolution;
|
||||
private final Sampler mutator;
|
||||
private final NoiseSampler mutator;
|
||||
private final double noiseAmp;
|
||||
private final Set<Biome> biomes;
|
||||
|
||||
public PipelineBiomeProvider(Pipeline pipeline, int resolution, Sampler mutator, double noiseAmp) {
|
||||
public PipelineBiomeProvider(Pipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
|
||||
this.resolution = resolution;
|
||||
this.mutator = mutator;
|
||||
this.noiseAmp = noiseAmp;
|
||||
@@ -82,8 +75,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
|
||||
|
||||
public Biome getBiome(int x, int z, long seed) {
|
||||
|
||||
x += (int) (mutator.getSample(seed + 1, x, z) * noiseAmp);
|
||||
z += (int) (mutator.getSample(seed + 2, x, z) * noiseAmp);
|
||||
x += mutator.noise(seed + 1, x, z) * noiseAmp;
|
||||
z += mutator.noise(seed + 2, x, z) * noiseAmp;
|
||||
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
@@ -97,7 +90,7 @@ public class PipelineBiomeProvider implements BiomeProvider {
|
||||
int xInChunk = x - chunkWorldX;
|
||||
int zInChunk = z - chunkWorldZ;
|
||||
|
||||
return biomeChunkCache.get(new SeededVector2Key(chunkWorldX, chunkWorldZ, seed)).get(xInChunk, zInChunk).getBiome();
|
||||
return biomeChunkCache.get(new SeededVector(seed, chunkWorldX, chunkWorldZ)).get(xInChunk, zInChunk).getBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public interface BiomeChunk {
|
||||
|
||||
PipelineBiome get(int xInChunk, int zInChunk);
|
||||
}
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||
|
||||
|
||||
/**
|
||||
@@ -10,7 +10,7 @@ import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
*/
|
||||
public interface Expander extends Stage {
|
||||
|
||||
PipelineBiome fillBiome(BiomeChunkImpl.ViewPoint viewPoint);
|
||||
PipelineBiome fillBiome(ViewPoint viewPoint);
|
||||
|
||||
@Override
|
||||
default int maxRelativeReadDistance() {
|
||||
@@ -18,7 +18,7 @@ public interface Expander extends Stage {
|
||||
}
|
||||
|
||||
@Override
|
||||
default PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint) {
|
||||
default PipelineBiome apply(ViewPoint viewPoint) {
|
||||
PipelineBiome currentBiome = viewPoint.getBiome();
|
||||
if(currentBiome == null) {
|
||||
return fillBiome(viewPoint);
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface Pipeline {
|
||||
BiomeChunk generateChunk(SeededVector worldCoordinates);
|
||||
|
||||
int getChunkSize();
|
||||
|
||||
Source getSource();
|
||||
|
||||
List<Stage> getStages();
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
public record SeededVector(long seed, int x, int z) {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof SeededVector that) {
|
||||
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = x;
|
||||
code = 31 * code + z;
|
||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public interface Source {
|
||||
PipelineBiome get(long seed, int x, int z);
|
||||
|
||||
Iterable<PipelineBiome> getBiomes();
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl.ViewPoint;
|
||||
|
||||
|
||||
public interface Stage {
|
||||
PipelineBiome apply(ViewPoint viewPoint);
|
||||
|
||||
int maxRelativeReadDistance();
|
||||
|
||||
default Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||
return biomes;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.biome;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.biome;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.biome;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.biome;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.biome.pipeline.v2.config;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
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.biome.pipeline.v2.PipelineBiomeProvider;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.PipelineImpl;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||
public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Value("resolution")
|
||||
@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;
|
||||
@Value("blend.sampler")
|
||||
@Default
|
||||
@Description("A sampler to use for blending the edges of biomes via domain warping.")
|
||||
protected @Meta NoiseSampler blendSampler = NoiseSampler.zero();
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
@Description("The amplitude at which to perform blending.")
|
||||
protected @Meta double blendAmplitude = 0d;
|
||||
@Value("pipeline.source")
|
||||
@Description("The Biome Source to use for initial population of biomes.")
|
||||
private @Meta Source source;
|
||||
@Value("pipeline.stages")
|
||||
@Description("A list of pipeline stages to apply to the result of #source")
|
||||
private @Meta List<@Meta Stage> stages;
|
||||
|
||||
@Override
|
||||
public BiomeProvider get() {
|
||||
return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config;
|
||||
|
||||
import com.dfsek.tectonic.api.depth.DepthTracker;
|
||||
import com.dfsek.tectonic.api.exception.LoadException;
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
+7
-7
@@ -1,27 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.source;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.source;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.SamplerSource;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.source.SamplerSource;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class SamplerSourceTemplate extends SourceTemplate {
|
||||
@Value("sampler")
|
||||
@Description("The sampler used to distribute biomes.")
|
||||
private @Meta Sampler noise;
|
||||
private @Meta NoiseSampler noise;
|
||||
|
||||
@Value("biomes")
|
||||
@Description("The biomes to be distributed.")
|
||||
+3
-3
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.source;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.source;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
|
||||
|
||||
public abstract class SourceTemplate implements ObjectTemplate<Source> {
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* 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.biome.pipeline.v2.config.stage;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public abstract class StageTemplate implements ObjectTemplate<Stage> {
|
||||
@Value("sampler")
|
||||
@Description("Sampler to use for stage distribution.")
|
||||
protected @Meta NoiseSampler noise;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.biome.pipeline.v2.config.stage.expander;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.expander.FractalExpander;
|
||||
|
||||
|
||||
public class ExpanderStageTemplate extends StageTemplate {
|
||||
@Override
|
||||
public Expander get() {
|
||||
return new FractalExpander(noise);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.stage.mutator;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.stage.mutators.BorderListStage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderListStage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
+6
-6
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.stage.mutator;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.stage.mutators.BorderStage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.BorderStage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
+6
-6
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.stage.mutator;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.stage.mutators.ReplaceListStage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceListStage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
+6
-6
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.config.stage.mutator;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.config.stage.mutator;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.stage.mutators.ReplaceStage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.ReplaceStage;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.biome.pipeline.v2.config.stage.mutator;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.config.stage.StageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators.SmoothStage;
|
||||
|
||||
|
||||
public class SmoothStageTemplate extends StageTemplate {
|
||||
@Override
|
||||
public Stage get() {
|
||||
return new SmoothStage(noise);
|
||||
}
|
||||
}
|
||||
+24
-34
@@ -1,25 +1,23 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.pipeline;
|
||||
|
||||
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public class BiomeChunkImpl implements BiomeChunk {
|
||||
|
||||
private final SeededVector2Key worldOrigin;
|
||||
private final SeededVector worldOrigin;
|
||||
private final int chunkOriginArrayIndex;
|
||||
private final int worldCoordinateScale;
|
||||
private final int size;
|
||||
private PipelineBiome[] biomes;
|
||||
|
||||
public BiomeChunkImpl(SeededVector2Key worldOrigin, PipelineImpl pipeline) {
|
||||
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
|
||||
|
||||
this.worldOrigin = worldOrigin;
|
||||
this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex();
|
||||
@@ -46,7 +44,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
for(int gridZ = 0; gridZ < gridSize; gridZ++) {
|
||||
int xIndex = gridOrigin + gridX * gridInterval;
|
||||
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||
biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed, xIndexToWorldCoordinate(xIndex),
|
||||
biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
|
||||
zIndexToWorldCoordinate(zIndex));
|
||||
}
|
||||
}
|
||||
@@ -73,13 +71,12 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
lookupArray = tempArray;
|
||||
|
||||
// Apply stage to working grid
|
||||
ViewPoint viewPoint = new ViewPoint(this, gridInterval, lookupArray, size);
|
||||
for(int gridZ = 0; gridZ < gridSize; gridZ = gridZ + 1) {
|
||||
for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) {
|
||||
int xIndex = gridOrigin + gridX * gridInterval;
|
||||
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||
viewPoint.set(gridX, gridZ, xIndex, zIndex);
|
||||
biomes[(xIndex * size) + zIndex] = stage.apply(viewPoint);
|
||||
biomes[(xIndex * size) + zIndex] = stage.apply(
|
||||
new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray, size));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,7 +98,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
// chunk samples points on the same overall grid.
|
||||
// Without this, shared chunk borders (required because of adjacent cell reads) will not be identical
|
||||
// because points would be sampled on grids at different offsets, resulting in artifacts at borders.
|
||||
return FloatingPointFunctions.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
|
||||
return (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
|
||||
}
|
||||
|
||||
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
|
||||
@@ -142,14 +139,14 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
}
|
||||
|
||||
private int xIndexToWorldCoordinate(int xIndex) {
|
||||
return (worldOrigin.x + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
}
|
||||
|
||||
private int zIndexToWorldCoordinate(int zIndex) {
|
||||
return (worldOrigin.z + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
}
|
||||
|
||||
private SeededVector2Key getOrigin() {
|
||||
private SeededVector getOrigin() {
|
||||
return worldOrigin;
|
||||
}
|
||||
|
||||
@@ -158,32 +155,25 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
*/
|
||||
public static class ViewPoint {
|
||||
private final BiomeChunkImpl chunk;
|
||||
private PipelineBiome biome;
|
||||
private final PipelineBiome biome;
|
||||
private final int gridInterval;
|
||||
private int gridX;
|
||||
private int gridZ;
|
||||
private int xIndex;
|
||||
private int zIndex;
|
||||
private final int gridX;
|
||||
private final int gridZ;
|
||||
private final int xIndex;
|
||||
private final int zIndex;
|
||||
private final PipelineBiome[] lookupArray;
|
||||
private final int size;
|
||||
|
||||
private ViewPoint(BiomeChunkImpl chunk, int gridInterval,
|
||||
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
|
||||
PipelineBiome[] lookupArray, int size) {
|
||||
this.chunk = chunk;
|
||||
this.gridInterval = gridInterval;
|
||||
this.gridX = 0;
|
||||
this.gridZ = 0;
|
||||
this.xIndex = 0;
|
||||
this.zIndex = 0;
|
||||
this.lookupArray = lookupArray;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public void set(int gridX, int gridZ, int xIndex, int zIndex) {
|
||||
this.gridX = gridX;
|
||||
this.gridZ = gridZ;
|
||||
this.xIndex = xIndex;
|
||||
this.zIndex = zIndex;
|
||||
this.lookupArray = lookupArray;
|
||||
this.size = size;
|
||||
this.biome = lookupArray[(this.xIndex * this.size) + this.zIndex];
|
||||
}
|
||||
|
||||
@@ -226,7 +216,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
}
|
||||
|
||||
public long worldSeed() {
|
||||
return chunk.getOrigin().seed;
|
||||
return chunk.getOrigin().seed();
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -1,16 +1,16 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.pipeline;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
|
||||
|
||||
public class PipelineImpl implements Pipeline {
|
||||
@@ -55,7 +55,7 @@ public class PipelineImpl implements Pipeline {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeChunk generateChunk(SeededVector2Key worldCoordinates) {
|
||||
public BiomeChunk generateChunk(SeededVector worldCoordinates) {
|
||||
return new BiomeChunkImpl(worldCoordinates, this);
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.source;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class SamplerSource implements Source {
|
||||
private final ProbabilityCollection<PipelineBiome> biomes;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public SamplerSource(ProbabilityCollection<PipelineBiome> biomes, NoiseSampler sampler) {
|
||||
this.biomes = biomes;
|
||||
this.sampler = sampler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PipelineBiome get(long seed, int x, int z) {
|
||||
return biomes.get(sampler, x, z, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<PipelineBiome> getBiomes() {
|
||||
return biomes.getContents();
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,10 +1,10 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.source;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.source;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public class SingleSource implements Source {
|
||||
+8
-9
@@ -1,17 +1,16 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.stage.expander;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.expander;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class FractalExpander implements Expander {
|
||||
|
||||
private final Sampler sampler;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public FractalExpander(Sampler sampler) {
|
||||
public FractalExpander(NoiseSampler sampler) {
|
||||
this.sampler = sampler;
|
||||
}
|
||||
|
||||
@@ -21,7 +20,7 @@ public class FractalExpander implements Expander {
|
||||
int xMod2 = viewPoint.gridX() % 2;
|
||||
int zMod2 = viewPoint.gridZ() % 2;
|
||||
|
||||
double roll = sampler.getSample(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||
|
||||
if(xMod2 == 1 && zMod2 == 0) { // Pick one of 2 neighbors on X axis randomly
|
||||
return roll > 0 ? viewPoint.getRelativeBiome(-1, 0) : viewPoint.getRelativeBiome(1, 0);
|
||||
+12
-13
@@ -1,14 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.stage.mutators;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.dfsek.seismic.type.vector.Vector2Int;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -17,15 +14,17 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.vector.Vector2Int;
|
||||
|
||||
|
||||
public class BorderListStage implements Stage {
|
||||
private final String border;
|
||||
private final Sampler Sampler;
|
||||
private final NoiseSampler noiseSampler;
|
||||
private final ProbabilityCollection<PipelineBiome> replaceDefault;
|
||||
private final String defaultReplace;
|
||||
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
|
||||
@@ -33,9 +32,9 @@ public class BorderListStage implements Stage {
|
||||
private final Vector2Int[] borderPoints;
|
||||
|
||||
public BorderListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String border, String defaultReplace,
|
||||
Sampler Sampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
|
||||
NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replaceDefault) {
|
||||
this.border = border;
|
||||
this.Sampler = Sampler;
|
||||
this.noiseSampler = noiseSampler;
|
||||
this.replaceDefault = replaceDefault;
|
||||
this.defaultReplace = defaultReplace;
|
||||
this.replace = replace;
|
||||
@@ -68,11 +67,11 @@ public class BorderListStage implements Stage {
|
||||
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
|
||||
if(current != null && current.getTags().contains(border)) {
|
||||
if(replace.containsKey(center)) {
|
||||
PipelineBiome replacement = replace.get(center).get(Sampler, viewPoint.worldX(), viewPoint.worldZ(),
|
||||
PipelineBiome replacement = replace.get(center).get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
|
||||
viewPoint.worldSeed());
|
||||
return replacement.isSelf() ? center : replacement;
|
||||
}
|
||||
PipelineBiome replacement = replaceDefault.get(Sampler, viewPoint.worldX(), viewPoint.worldZ(),
|
||||
PipelineBiome replacement = replaceDefault.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(),
|
||||
viewPoint.worldSeed());
|
||||
return replacement.isSelf() ? center : replacement;
|
||||
}
|
||||
+11
-12
@@ -1,14 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.stage.mutators;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.dfsek.seismic.type.vector.Vector2Int;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -16,22 +13,24 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.vector.Vector2Int;
|
||||
|
||||
|
||||
public class BorderStage implements Stage {
|
||||
private final String border;
|
||||
private final Sampler Sampler;
|
||||
private final NoiseSampler noiseSampler;
|
||||
private final ProbabilityCollection<PipelineBiome> replace;
|
||||
private final String replaceTag;
|
||||
private final Vector2Int[] borderPoints;
|
||||
|
||||
public BorderStage(String border, String replaceTag, Sampler Sampler, ProbabilityCollection<PipelineBiome> replace) {
|
||||
public BorderStage(String border, String replaceTag, NoiseSampler noiseSampler, ProbabilityCollection<PipelineBiome> replace) {
|
||||
this.border = border;
|
||||
this.Sampler = Sampler;
|
||||
this.noiseSampler = noiseSampler;
|
||||
this.replace = replace;
|
||||
this.replaceTag = replaceTag;
|
||||
List<Vector2Int> points = new ArrayList<>();
|
||||
@@ -51,7 +50,7 @@ public class BorderStage implements Stage {
|
||||
for(Vector2Int point : borderPoints) {
|
||||
PipelineBiome current = viewPoint.getRelativeBiome(point.getX(), point.getZ());
|
||||
if(current != null && current.getTags().contains(border)) {
|
||||
PipelineBiome replacement = replace.get(Sampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||
PipelineBiome replacement = replace.get(noiseSampler, viewPoint.worldX(), viewPoint.worldZ(), viewPoint.worldSeed());
|
||||
return replacement.isSelf() ? center : replacement;
|
||||
}
|
||||
}
|
||||
+8
-9
@@ -1,33 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.stage.mutators;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class ReplaceListStage implements Stage {
|
||||
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
|
||||
private final Sampler sampler;
|
||||
private final NoiseSampler sampler;
|
||||
private final ProbabilityCollection<PipelineBiome> replaceDefault;
|
||||
private final String defaultTag;
|
||||
|
||||
public ReplaceListStage(Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace, String defaultTag,
|
||||
ProbabilityCollection<PipelineBiome> replaceDefault, Sampler sampler) {
|
||||
ProbabilityCollection<PipelineBiome> replaceDefault, NoiseSampler sampler) {
|
||||
this.replace = replace;
|
||||
this.sampler = sampler;
|
||||
this.defaultTag = defaultTag;
|
||||
+8
-9
@@ -1,30 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.stage.mutators;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
|
||||
public class ReplaceStage implements Stage {
|
||||
private final String replaceableTag;
|
||||
private final ProbabilityCollection<PipelineBiome> replace;
|
||||
private final Sampler sampler;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, Sampler sampler) {
|
||||
public ReplaceStage(String replaceable, ProbabilityCollection<PipelineBiome> replace, NoiseSampler sampler) {
|
||||
this.replaceableTag = replaceable;
|
||||
this.replace = replace;
|
||||
this.sampler = sampler;
|
||||
+9
-10
@@ -1,26 +1,25 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.biome.pipeline.stage.mutators;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class SmoothStage implements Stage {
|
||||
|
||||
private final Sampler sampler;
|
||||
private final NoiseSampler sampler;
|
||||
|
||||
public SmoothStage(Sampler sampler) {
|
||||
public SmoothStage(NoiseSampler sampler) {
|
||||
this.sampler = sampler;
|
||||
}
|
||||
|
||||
@@ -31,7 +30,7 @@ public class SmoothStage implements Stage {
|
||||
PipelineBiome left = viewPoint.getRelativeBiome(0, 1);
|
||||
PipelineBiome right = viewPoint.getRelativeBiome(0, -1);
|
||||
|
||||
double roll = sampler.getSample(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||
double roll = sampler.noise(viewPoint.worldSeed(), viewPoint.worldX(), viewPoint.worldZ());
|
||||
|
||||
boolean vert = Objects.equals(top, bottom);
|
||||
boolean horiz = Objects.equals(left, right);
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
schema-version: 1
|
||||
contributors:
|
||||
- Terra contributors
|
||||
id: command-locate
|
||||
id: biome-provider-pipeline-v2
|
||||
version: @VERSION@
|
||||
entrypoints:
|
||||
- "com.dfsek.terra.addons.commands.locate.LocateCommandAddon"
|
||||
- "com.dfsek.terra.addons.biome.pipeline.v2.BiomePipelineAddon"
|
||||
website:
|
||||
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||
source: https://github.com/PolyhedralDev/Terra
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020-2025 Polyhedral Development
|
||||
Copyright (c) 2020-2023 Polyhedral Development
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
# biome-provider-pipeline-2
|
||||
# biome-provider-pipeline
|
||||
|
||||
The second version of the Biome Pipeline, a procedural biome provider that uses a series
|
||||
Implements the Biome Pipeline, a procedural biome provider that uses a series
|
||||
of "stages" to apply "mutations" to a 2D grid of biomes.
|
||||
|
||||
Version 2 is a re-implementation of the original addon with the primary goal of providing
|
||||
consistent scaling for noise relative to the world
|
||||
(See https://github.com/PolyhedralDev/Terra/issues/264 for more details), and has been
|
||||
included as a separate addon to maintain parity with packs utilizing the first version.
|
||||
|
||||
This addon registers the `PIPELINE` biome provider type, and all associated
|
||||
configurations.
|
||||
@@ -1,5 +1,5 @@
|
||||
version = version("2.0.0")
|
||||
version = version("1.0.2")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
}
|
||||
}
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.biome.pipeline;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeExpander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.api.util.vector.Vector2;
|
||||
|
||||
|
||||
public class BiomeHolderImpl implements BiomeHolder {
|
||||
private final Vector2.Mutable origin;
|
||||
private final int width;
|
||||
private final int offset;
|
||||
private BiomeDelegate[][] biomes;
|
||||
|
||||
public BiomeHolderImpl(int width, Vector2.Mutable origin) {
|
||||
width += 4;
|
||||
this.width = width;
|
||||
biomes = new BiomeDelegate[width][width];
|
||||
this.origin = origin;
|
||||
this.offset = 2;
|
||||
}
|
||||
|
||||
private BiomeHolderImpl(BiomeDelegate[][] biomes, Vector2.Mutable origin, int width, int offset) {
|
||||
this.biomes = biomes;
|
||||
this.origin = origin;
|
||||
this.width = width;
|
||||
this.offset = 2 * offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeHolder expand(BiomeExpander expander, long seed) {
|
||||
BiomeDelegate[][] old = biomes;
|
||||
int newWidth = width * 2 - 1;
|
||||
|
||||
biomes = new BiomeDelegate[newWidth][newWidth];
|
||||
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int z = 0; z < width; z++) {
|
||||
biomes[x * 2][z * 2] = old[x][z];
|
||||
if(z != width - 1)
|
||||
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
|
||||
old[x][z + 1]);
|
||||
if(x != width - 1)
|
||||
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z],
|
||||
old[x + 1][z]);
|
||||
if(x != width - 1 && z != width - 1)
|
||||
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z],
|
||||
old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
|
||||
}
|
||||
}
|
||||
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mutate(BiomeMutator mutator, long seed) {
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int z = 0; z < width; z++) {
|
||||
BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(this, x, z);
|
||||
biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ(), seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(BiomeSource source, long seed) {
|
||||
for(int x = 0; x < width; x++) {
|
||||
for(int z = 0; z < width; z++) {
|
||||
biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z, seed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeDelegate getBiome(int x, int z) {
|
||||
x += offset;
|
||||
z += offset;
|
||||
return getBiomeRaw(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeDelegate getBiomeRaw(int x, int z) {
|
||||
if(x >= width || z >= width || x < 0 || z < 0) return null;
|
||||
return biomes[x][z];
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.biome.pipeline;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.api.util.vector.Vector2;
|
||||
|
||||
|
||||
public class BiomePipeline {
|
||||
private final BiomeSource source;
|
||||
private final List<Stage> stages;
|
||||
private final int size;
|
||||
private final int init;
|
||||
|
||||
private BiomePipeline(BiomeSource source, List<Stage> stages, int size, int init) {
|
||||
this.source = source;
|
||||
this.stages = stages;
|
||||
this.size = size;
|
||||
this.init = init;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get biomes in a chunk
|
||||
*
|
||||
* @param x Chunk X coord
|
||||
* @param z Chunk Z coord
|
||||
*
|
||||
* @return BiomeHolder containing biomes.
|
||||
*/
|
||||
public BiomeHolder getBiomes(int x, int z, long seed) {
|
||||
BiomeHolder holder = new BiomeHolderImpl(init, Vector2.of(x * (init - 1), z * (init - 1)).mutable());
|
||||
holder.fill(source, seed);
|
||||
for(Stage stage : stages) holder = stage.apply(holder, seed);
|
||||
return holder;
|
||||
}
|
||||
|
||||
public BiomeSource getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
public List<Stage> getStages() {
|
||||
return Collections.unmodifiableList(stages);
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public static final class BiomePipelineBuilder {
|
||||
private final int init;
|
||||
private final List<Stage> stages = new ArrayList<>();
|
||||
private int expand;
|
||||
|
||||
public BiomePipelineBuilder(int init) {
|
||||
this.init = init;
|
||||
expand = init;
|
||||
}
|
||||
|
||||
public BiomePipeline build(BiomeSource source) {
|
||||
for(Stage stage : stages) {
|
||||
if(stage.isExpansion()) expand = expand * 2 - 1;
|
||||
}
|
||||
|
||||
return new BiomePipeline(source, stages, expand, init);
|
||||
}
|
||||
|
||||
public BiomePipelineBuilder addStage(Stage stage) {
|
||||
stages.add(stage);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
@@ -8,21 +8,23 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline;
|
||||
|
||||
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.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.BiomeDelegateLoader;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.BiomePipelineTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.PipelineBiomeLoader;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.source.SamplerSourceTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.SamplerSourceTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.expander.ExpanderStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothStageTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderListMutatorTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.BorderMutatorTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceListMutatorTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.ReplaceMutatorTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.config.stage.mutator.SmoothMutatorTemplate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
@@ -39,13 +41,13 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
public class BiomePipelineAddon implements AddonInitializer {
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<Source>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeSource>>> SOURCE_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
|
||||
public static final TypeKey<Supplier<ObjectTemplate<Stage>>> STAGE_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
public static final TypeKey<Supplier<ObjectTemplate<BiomeProvider>>> PROVIDER_REGISTRY_KEY = new TypeKey<>() {
|
||||
};
|
||||
private static final Logger logger = LoggerFactory.getLogger(BiomePipelineAddon.class);
|
||||
@Inject
|
||||
private Platform platform;
|
||||
|
||||
@@ -63,7 +65,7 @@ public class BiomePipelineAddon implements AddonInitializer {
|
||||
providerRegistry.register(addon.key("PIPELINE"), BiomePipelineTemplate::new);
|
||||
})
|
||||
.then(event -> {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<Source>>> sourceRegistry = event.getPack().getOrCreateRegistry(
|
||||
CheckedRegistry<Supplier<ObjectTemplate<BiomeSource>>> sourceRegistry = event.getPack().getOrCreateRegistry(
|
||||
SOURCE_REGISTRY_KEY);
|
||||
sourceRegistry.register(addon.key("SAMPLER"), SamplerSourceTemplate::new);
|
||||
})
|
||||
@@ -71,11 +73,11 @@ public class BiomePipelineAddon implements AddonInitializer {
|
||||
CheckedRegistry<Supplier<ObjectTemplate<Stage>>> stageRegistry = event.getPack().getOrCreateRegistry(
|
||||
STAGE_REGISTRY_KEY);
|
||||
stageRegistry.register(addon.key("FRACTAL_EXPAND"), ExpanderStageTemplate::new);
|
||||
stageRegistry.register(addon.key("SMOOTH"), SmoothStageTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE"), ReplaceStageTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListStageTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER"), BorderStageTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER_LIST"), BorderListStageTemplate::new);
|
||||
stageRegistry.register(addon.key("SMOOTH"), SmoothMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE"), ReplaceMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("REPLACE_LIST"), ReplaceListMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER"), BorderMutatorTemplate::new);
|
||||
stageRegistry.register(addon.key("BORDER_LIST"), BorderListMutatorTemplate::new);
|
||||
})
|
||||
.failThrough();
|
||||
platform.getEventManager()
|
||||
@@ -83,7 +85,12 @@ public class BiomePipelineAddon implements AddonInitializer {
|
||||
.register(addon, ConfigPackPostLoadEvent.class)
|
||||
.then(event -> {
|
||||
Registry<Biome> biomeRegistry = event.getPack().getRegistry(Biome.class);
|
||||
event.getPack().applyLoader(PipelineBiome.class, new PipelineBiomeLoader(biomeRegistry));
|
||||
event.getPack().applyLoader(BiomeDelegate.class, new BiomeDelegateLoader(biomeRegistry));
|
||||
});
|
||||
|
||||
if(platform.getTerraConfig().isDebugLog())
|
||||
logger.warn(
|
||||
"The biome-provider-pipeline addon is deprecated and scheduled for removal in Terra 7.0. It is recommended to use the" +
|
||||
" biome-provider-pipeline-v2 addon for future pack development instead.");
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomePipelineColumn implements Column<Biome> {
|
||||
class BiomePipelineColumn implements Column<Biome> {
|
||||
private final int min;
|
||||
private final int max;
|
||||
|
||||
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* 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.biome.pipeline;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomePipelineProvider implements BiomeProvider {
|
||||
private final LoadingCache<SeededVector, BiomeHolder> holderCache;
|
||||
private final BiomePipeline pipeline;
|
||||
private final int resolution;
|
||||
private final NoiseSampler mutator;
|
||||
private final double noiseAmp;
|
||||
|
||||
private final Set<Biome> biomes;
|
||||
|
||||
public BiomePipelineProvider(BiomePipeline pipeline, int resolution, NoiseSampler mutator, double noiseAmp) {
|
||||
this.resolution = resolution;
|
||||
this.mutator = mutator;
|
||||
this.noiseAmp = noiseAmp;
|
||||
holderCache = Caffeine.newBuilder()
|
||||
.maximumSize(1024)
|
||||
.build(key -> pipeline.getBiomes(key.x, key.z, key.seed));
|
||||
this.pipeline = pipeline;
|
||||
|
||||
Set<BiomeDelegate> biomeSet = new HashSet<>();
|
||||
pipeline.getSource().getBiomes().forEach(biomeSet::add);
|
||||
Iterable<BiomeDelegate> result = biomeSet;
|
||||
for(Stage stage : pipeline.getStages()) {
|
||||
result = stage.getBiomes(result); // pass through all stages
|
||||
}
|
||||
this.biomes = new HashSet<>();
|
||||
Iterable<BiomeDelegate> finalResult = result;
|
||||
result.forEach(biomeDelegate -> {
|
||||
if(biomeDelegate.isEphemeral()) {
|
||||
|
||||
StringBuilder biomeList = new StringBuilder("\n");
|
||||
StreamSupport.stream(finalResult.spliterator(), false)
|
||||
.sorted(Comparator.comparing(StringIdentifiable::getID))
|
||||
.forEach(delegate -> biomeList
|
||||
.append(" - ")
|
||||
.append(delegate.getID())
|
||||
.append(':')
|
||||
.append(delegate.getClass().getCanonicalName())
|
||||
.append('\n'));
|
||||
throw new IllegalArgumentException("Biome Pipeline leaks ephemeral biome \"" + biomeDelegate.getID() +
|
||||
"\". Ensure there is a stage to guarantee replacement of the ephemeral biome. Biomes: " +
|
||||
biomeList);
|
||||
}
|
||||
this.biomes.add(biomeDelegate.getBiome());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z, long seed) {
|
||||
return getBiome(x, z, seed);
|
||||
}
|
||||
|
||||
public Biome getBiome(int x, int z, long seed) {
|
||||
x += mutator.noise(seed + 1, x, z) * noiseAmp;
|
||||
z += mutator.noise(seed + 2, x, z) * noiseAmp;
|
||||
|
||||
|
||||
x /= resolution;
|
||||
z /= resolution;
|
||||
|
||||
int fdX = Math.floorDiv(x, pipeline.getSize());
|
||||
int fdZ = Math.floorDiv(z, pipeline.getSize());
|
||||
return holderCache.get(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(),
|
||||
z - fdZ * pipeline.getSize()).getBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Biome> getBaseBiome(int x, int z, long seed) {
|
||||
return Optional.of(getBiome(x, z, seed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Biome> getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Column<Biome> getColumn(int x, int z, long seed, int min, int max) {
|
||||
return new BiomePipelineColumn(this, min, max, x, z, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resolution() {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
private record SeededVector(int x, int z, long seed) {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof SeededVector that) {
|
||||
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = x;
|
||||
code = 31 * code + z;
|
||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public interface BiomeChunk {
|
||||
|
||||
PipelineBiome get(int xInChunk, int zInChunk);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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.biome.pipeline.api;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeExpander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.type.BiomeMutator;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
|
||||
|
||||
public interface BiomeHolder {
|
||||
BiomeHolder expand(BiomeExpander expander, long seed);
|
||||
|
||||
void mutate(BiomeMutator mutator, long seed);
|
||||
|
||||
void fill(BiomeSource source, long seed);
|
||||
|
||||
BiomeDelegate getBiome(int x, int z);
|
||||
|
||||
BiomeDelegate getBiomeRaw(int x, int z);
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
|
||||
|
||||
public interface Pipeline {
|
||||
BiomeChunk generateChunk(SeededVector2Key worldCoordinates);
|
||||
|
||||
int getChunkSize();
|
||||
|
||||
Source getSource();
|
||||
|
||||
List<Stage> getStages();
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
|
||||
|
||||
public interface Source {
|
||||
PipelineBiome get(long seed, int x, int z);
|
||||
|
||||
Iterable<PipelineBiome> getBiomes();
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.BiomeChunkImpl;
|
||||
|
||||
|
||||
public interface Stage {
|
||||
PipelineBiome apply(BiomeChunkImpl.ViewPoint viewPoint);
|
||||
|
||||
int maxRelativeReadDistance();
|
||||
|
||||
default Iterable<PipelineBiome> getBiomes(Iterable<PipelineBiome> biomes) {
|
||||
return biomes;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
public interface BiomeDelegate extends StringIdentifiable {
|
||||
static BiomeDelegate ephemeral(String id) {
|
||||
return new EphemeralBiomeDelegate(id);
|
||||
}
|
||||
|
||||
static BiomeDelegate from(Biome biome) {
|
||||
return new DelegatedBiome(biome);
|
||||
}
|
||||
|
||||
static BiomeDelegate self() {
|
||||
return SelfDelegate.INSTANCE;
|
||||
}
|
||||
|
||||
Biome getBiome();
|
||||
|
||||
Set<String> getTags();
|
||||
|
||||
default boolean isEphemeral() {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean isSelf() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
final class DelegatedBiome implements BiomeDelegate {
|
||||
private final Biome biome;
|
||||
|
||||
public DelegatedBiome(Biome biome) {
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return biome.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof DelegatedBiome that)) return false;
|
||||
return that.biome.equals(this.biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return biome.getTags();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return biome.getID();
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
final class EphemeralBiomeDelegate implements BiomeDelegate {
|
||||
private final Set<String> tags;
|
||||
private final String id;
|
||||
|
||||
public EphemeralBiomeDelegate(String id) {
|
||||
this.id = id;
|
||||
tags = new HashSet<>();
|
||||
tags.add(id);
|
||||
tags.add("ALL");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
throw new UnsupportedOperationException("Cannot get biome from ephemeral delegate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEphemeral() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof EphemeralBiomeDelegate that)) return false;
|
||||
|
||||
return this.id.equals(that.id);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.api.delegate;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
final class SelfDelegate implements BiomeDelegate {
|
||||
public static final SelfDelegate INSTANCE = new SelfDelegate();
|
||||
|
||||
private SelfDelegate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
throw new UnsupportedOperationException("Cannot get biome from self delegate");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelf() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEphemeral() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getTags() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "SELF";
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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.biome.pipeline.api.stage;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
|
||||
|
||||
public interface Stage {
|
||||
BiomeHolder apply(BiomeHolder in, long seed);
|
||||
|
||||
boolean isExpansion();
|
||||
|
||||
Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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.biome.pipeline.api.stage.type;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
|
||||
|
||||
public interface BiomeExpander {
|
||||
BiomeDelegate getBetween(double x, double z, long seed, BiomeDelegate... others);
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.biome.pipeline.api.stage.type;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.BiomeHolder;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
|
||||
|
||||
public interface BiomeMutator {
|
||||
BiomeDelegate mutate(ViewPoint viewPoint, double x, double z, long seed);
|
||||
|
||||
default Iterable<BiomeDelegate> getBiomes(Iterable<BiomeDelegate> biomes) {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
class ViewPoint {
|
||||
private final BiomeHolder biomes;
|
||||
private final int offX;
|
||||
private final int offZ;
|
||||
|
||||
public ViewPoint(BiomeHolder biomes, int offX, int offZ) {
|
||||
this.biomes = biomes;
|
||||
this.offX = offX;
|
||||
this.offZ = offZ;
|
||||
}
|
||||
|
||||
|
||||
public BiomeDelegate getBiome(int x, int z) {
|
||||
return biomes.getBiomeRaw(x + offX, z + offZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||
|
||||
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 com.dfsek.terra.addons.biome.pipeline.api.delegate.BiomeDelegate;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
public class BiomeDelegateLoader implements TypeLoader<BiomeDelegate> {
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
|
||||
public BiomeDelegateLoader(Registry<Biome> biomeRegistry) {
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeDelegate load(@NotNull AnnotatedType t, @NotNull Object c, @NotNull ConfigLoader loader, DepthTracker depthTracker)
|
||||
throws LoadException {
|
||||
if(c.equals("SELF")) return BiomeDelegate.self();
|
||||
return biomeRegistry
|
||||
.getByID((String) c)
|
||||
.map(BiomeDelegate::from)
|
||||
.orElseGet(() -> BiomeDelegate.ephemeral((String) c));
|
||||
}
|
||||
}
|
||||
+22
-23
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2025 Polyhedral Development
|
||||
* 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.
|
||||
@@ -7,49 +7,48 @@
|
||||
|
||||
package com.dfsek.terra.addons.biome.pipeline.config;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Description;
|
||||
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.biome.pipeline.PipelineBiomeProvider;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.pipeline.PipelineImpl;
|
||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.BiomePipelineProvider;
|
||||
import com.dfsek.terra.addons.biome.pipeline.api.stage.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.source.BiomeSource;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||
public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Value("resolution")
|
||||
public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
@Value("pipeline.initial-size")
|
||||
@Default
|
||||
@Description("""
|
||||
The resolution at which to sample biomes.
|
||||
The initial size of biome chunks. This value must be at least 2.
|
||||
<b>This is not the final size of biome chunks. Final chunks will be much larger</b>.
|
||||
|
||||
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;
|
||||
@Value("blend.sampler")
|
||||
@Default
|
||||
@Description("A sampler to use for blending the edges of biomes via domain warping.")
|
||||
protected @Meta Sampler blendSampler = Sampler.zero();
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
@Description("The amplitude at which to perform blending.")
|
||||
protected @Meta double blendAmplitude = 0d;
|
||||
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
|
||||
and subtract 1. (The size is also printed to the server console if you
|
||||
have debug mode enabled)""")
|
||||
private @Meta int initialSize = 2;
|
||||
|
||||
@Value("pipeline.source")
|
||||
@Description("The Biome Source to use for initial population of biomes.")
|
||||
private @Meta Source source;
|
||||
private @Meta BiomeSource source;
|
||||
|
||||
@Value("pipeline.stages")
|
||||
@Description("A list of pipeline stages to apply to the result of #source")
|
||||
private @Meta List<@Meta Stage> stages;
|
||||
|
||||
@Override
|
||||
public BiomeProvider get() {
|
||||
return new PipelineBiomeProvider(new PipelineImpl(source, stages, resolution, 128), resolution, blendSampler, blendAmplitude);
|
||||
BiomePipeline.BiomePipelineBuilder biomePipelineBuilder = new BiomePipeline.BiomePipelineBuilder(initialSize);
|
||||
stages.forEach(biomePipelineBuilder::addStage);
|
||||
BiomePipeline pipeline = biomePipelineBuilder.build(source);
|
||||
return new BiomePipelineProvider(pipeline, resolution, blend, blendAmp);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user