Compare commits

...

84 Commits

Author SHA1 Message Date
Zoë Gidiere c9d7af5274 fix padding 2025-06-07 01:23:44 -06:00
Zoë Gidiere 3269f9ec8b Initial work on supporting chunk based bending and interpolation in Layered Generator 2025-06-07 01:17:24 -06:00
Zoë Gidiere 619c2156cd Use seismic func for perf 2 2025-06-05 22:47:16 -06:00
Zoë Gidiere 0e211065bc Fix build again 2025-06-05 22:44:19 -06:00
Zoë Gidiere bc1213b220 Use Seismic function for perf 2025-06-05 22:44:07 -06:00
Zoë Gidiere f04c9b3e73 Fix build 2025-06-05 22:40:11 -06:00
Zoë Gidiere e079cdfcc0 Merge branch 'dev/7.0-2' into dev/layered-generator 2025-06-05 21:04:06 -06:00
Zoë Gidiere 4eace9e7fb Merge remote-tracking branch 'origin/master' into dev/7.0-2 2025-06-05 21:03:58 -06:00
Zoë Gidiere d90a4200fe Update gradle-build.yml 2025-06-05 19:19:43 -06:00
Zoë Gidiere 39ae1fdf93 Merge branch 'master' into dev/7.0-2 2025-06-05 17:51:01 -06:00
Zoë Gidiere af9fb211a8 bump fabric minecraft dep 2025-06-05 17:50:44 -06:00
Zoë Gidiere e9d1add6af Merge branch 'master' into dev/7.0-2 2025-06-05 17:21:00 -06:00
Zoë Gidiere e4395cec83 bump version 2025-06-05 17:18:55 -06:00
Christian Bergschneider 94d135c66c Refactor MinestomBiomeLoader to use DynamicRegistry directly
Simplified biome loading by removing dependency on MinecraftServer and using DynamicRegistry.Key directly. This improves code maintainability and aligns with updated API usage.
2025-06-05 17:04:37 -06:00
Zoë Gidiere 1881051191 Merge pull request #504 from everbuild-org/dev/7.0-2
Apply biomes to minestom instances
2025-06-05 08:16:00 +00:00
Christian Bergschneider 28132e0f13 resolve merge conflicts 2025-06-05 10:08:58 +02:00
Christian Bergschneider 1ef34469cb Merge remote-tracking branch 'ckyuri/dev/7.0-2' into dev/7.0-2 2025-06-05 10:03:50 +02:00
kyuri e79ea4ab82 Minestom Latest - Update (#499)
* Bukkit Build Fix

* remove comments

* remove papermc repo from gradle settings

* add back gradle shasum

* fix formatting, update gradle hash

* Minestom Updated to latest version as of now 4/12/2025

Updated method names to new documentation and changed minestom versioning.

- Paper Build version was changed as I had issues building at all with the snapshot version. So it was changed to a generic version but everything still builds fine.

* Bug Fix - Entity Type was parsing a value that was incorrect and causing issues to load the world.

EntityType.fromId(Integer.parseInt(id));
to
delegate = EntityType.fromKey(id);

* Reverted changes to comply with build version requirements and avoiding pulling functionality out of a common existing function

---------

Co-authored-by: Peter Pan <peter@never.lan>
Co-authored-by: Zoë Gidiere <duplexsys@protonmail.com>
2025-06-04 23:38:42 -06:00
Zoë Gidiere 4450a56ef0 Merge branch 'dev/7.0-2' into dev/7.0-2 2025-06-05 05:38:32 +00:00
Christian Bergschneider a061660e46 chore: Update Minestom version to 1_21_5-4d91778331
This commit updates the Minestom dependency to the latest tagged version. Ensures compatibility with new features and fixes in the updated Minestom release.
2025-06-04 21:52:46 +02:00
Christian Bergschneider abdff16a0a Merge remote-tracking branch 'origin/dev/7.0-2' into dev/7.0-2
# Conflicts:
#	buildSrc/src/main/kotlin/Versions.kt
2025-06-04 21:43:33 +02:00
Christian Bergschneider c08e973e3e feat: provide default MinestomBlockEntity implementation
Introduce the `MinestomBlockEntity` class to represent block entities and hook into the block system. Update `DefaultBlockEntityFactory` to create `MinestomBlockEntity` instances and adjust `TerraMinestomWorldBuilder` initialization for factory injection. These changes improve extensibility and block entity management.
2025-06-04 21:34:04 +02:00
Christian Bergschneider b12fe77f32 feat: add fine-grained biome control to Minestom world builder
Introduced a `doFineGrainedBiomes` flag to allow fine-grained biome control per chunk. This helps mitigate client disconnection issues caused by a Minestom biome encoding bug, with a plan to deprecate once the bug is resolved. Adjusted relevant classes and the example implementation to support this feature.
2025-06-04 21:25:35 +02:00
Zoë Gidiere bab8923f1e update overworld version 2025-06-04 00:21:14 -06:00
Zoë Gidiere 28d93d158e fix up 2025-06-03 22:52:26 -06:00
Zoë Gidiere 118dc32d64 Merge branch 'master' into dev/7.0-2 2025-06-03 22:38:32 -06:00
Zoë Gidiere b4068e6c59 Merge branch 'dev/1.21.5' 2025-06-03 22:28:48 -06:00
Zoë Gidiere b143c72d0e Dev/1.21.5 (#495)
* Bukkit Build Fix (#494)

* Bukkit Build Fix

* remove comments

* remove papermc repo from gradle settings

* add back gradle shasum

* fix formatting, update gradle hash

* Initial Fabric 1.21.5

* Updated dependencies

* Updated SpawnerData with backwards compat

* Updated dependencies

* Updated setBlockState usage - needs verifying as flags are confusing

* Refactored Bukkit NMS packages

* Initial attempt at updating mixin-commons

* Continue fabric 1.21.5 WIP

* Some additional logging

* Update deps

* Build fixes and update allay

* Add oak to authors

---------

Co-authored-by: Mikal <Ifiht@users.noreply.github.com>
Co-authored-by: OakLoaf <oak@beaconstudios.org>
2025-06-03 22:20:23 -06:00
Zoë Gidiere 5f5e70970b Add oak to authors 2025-06-03 21:40:14 -06:00
Zoë Gidiere ec812ef5fb Build fixes and update allay 2025-06-03 21:33:56 -06:00
Zoë Gidiere 85826071cb Update deps 2025-06-03 20:25:55 -06:00
Christian Bergschneider d9a4d64b17 Merge remote-tracking branch 'origin/dev/7.0-2' into dev/7.0-2 2025-06-04 00:05:56 +02:00
Christian Bergschneider 56a1feb708 refactor: move biomes to use user-defined naming conventions.
Replaced "Custom" with "UserDefined" in biome classes, factories, and references for consistency and clarity. Updated relevant imports, method signatures, and internal logic to align with the new terminology. This change improves readability and better represents the purpose of these biome-related components.
2025-06-04 00:05:15 +02:00
Zoë Gidiere c4f093210a Some additional logging 2025-06-03 15:15:07 -06:00
Christian Bergschneider 858adfe866 feat: initial custom biome implementation 2025-06-03 22:41:31 +02:00
Zoë Gidiere f14d22b264 Continue fabric 1.21.5 WIP 2025-06-03 13:59:11 -06:00
Zoë Gidiere 35bd33e256 Merge branch 'dev/7.0-2' into dev/layered-generator 2025-06-03 13:44:03 -06:00
Zoë Gidiere bdd80d7832 Merge branch 'dev/seismic' into dev/7.0-2 2025-06-03 04:37:11 -06:00
Zoë Gidiere adfdb8d63c update versions 2025-06-03 04:37:03 -06:00
Christian Bergschneider 5e1c9d8ebe fix: generation stages not being able to reference eachother 2025-06-02 00:34:48 +02:00
Christian Bergschneider 5dff25670c refactor: minestom chunk storage to improve memory efficiency
Replaced 3D array with a 1D array for chunk block storage and adjusted related logic to use calculated indices. Updated block type comparison to use state IDs instead of block IDs for consistency and correctness.
2025-05-30 09:13:04 +02:00
Christian Bergschneider 089b25dea4 feat: update Minestom version and replace deprecated ItemComponent API
Updated the Minestom library to version 1_21_5-69b9a5d844 and migrated from the deprecated `ItemComponent` API to `DataComponents`. This ensures compatibility with the latest changes and improves maintainability.
2025-05-27 23:25:34 +02:00
Christian Bergschneider 1dd59c378e refactor(minestom): replace static singleton access to platform with dependency injection for better modularity
Renamed `MinestomPlatform` to `TerraMinestomPlatform` and updated `TerraMinestomWorldBuilder` to utilize the platform instance directly. Simplified world builder initialization and improved code clarity.
2025-05-27 22:58:16 +02:00
Christian Bergschneider d97fb4ff7b chore: update paper version 2025-05-27 22:50:03 +02:00
OakLoaf 016961c19c Initial attempt at updating mixin-commons 2025-04-17 17:41:45 +01:00
OakLoaf 9f3e225b62 Refactored Bukkit NMS packages 2025-04-17 16:32:59 +01:00
ckyuri 761a014ea5 Reverted changes to comply with build version requirements and avoiding pulling functionality out of a common existing function 2025-04-16 15:54:20 +01:00
ckyuri 9749eecd87 Merge remote-tracking branch 'origin/dev/7.0-2' into dev/7.0-2 2025-04-12 14:11:07 +01:00
ckyuri 32cc4976c8 Bug Fix - Entity Type was parsing a value that was incorrect and causing issues to load the world.
EntityType.fromId(Integer.parseInt(id));
to
delegate = EntityType.fromKey(id);
2025-04-12 14:10:54 +01:00
kyuri e2e0e292b7 Merge branch 'dev/7.0-2' into dev/7.0-2 2025-04-12 12:22:00 +01:00
ckyuri 227bfe7b29 Minestom Updated to latest version as of now 4/12/2025
Updated method names to new documentation and changed minestom versioning.

- Paper Build version was changed as I had issues building at all with the snapshot version. So it was changed to a generic version but everything still builds fine.
2025-04-12 11:54:48 +01:00
OakLoaf c95df25d30 Updated setBlockState usage - needs verifying as flags are confusing 2025-03-27 20:22:35 +00:00
OakLoaf 0adca3c227 Updated dependencies 2025-03-27 20:21:13 +00:00
OakLoaf 782b300d1f Updated SpawnerData with backwards compat 2025-03-27 19:22:34 +00:00
OakLoaf 967a4a0b2b Updated dependencies 2025-03-27 19:22:23 +00:00
Zoë Gidiere d3df5e56c3 Initial Fabric 1.21.5 2025-03-25 16:26:43 -06:00
Mikal dabc2359b3 Bukkit Build Fix (#494)
* Bukkit Build Fix

* remove comments

* remove papermc repo from gradle settings

* add back gradle shasum

* fix formatting, update gradle hash
2025-03-25 16:25:51 -06:00
Peter Pan d33d4af296 fix formatting, update gradle hash 2025-03-20 14:51:12 -04:00
Peter Pan fb0dbda296 add back gradle shasum 2025-03-20 11:01:41 -04:00
Peter Pan 4c860ca4ae remove papermc repo from gradle settings 2025-03-20 10:53:49 -04:00
Peter Pan b6e4543625 remove comments 2025-03-20 10:43:29 -04:00
Peter Pan 0921dfb204 Bukkit Build Fix 2025-03-19 15:54:11 -04:00
Zoe Gidiere 3eb6f89776 Merge remote-tracking branch 'origin/master' into dev/layered-generator 2024-10-13 18:51:14 -06:00
Astrash e51fb9c580 Merge branch 'ver/6.4.0' into dev/layered-generator 2023-10-02 09:48:15 +11:00
Astrash bd139a8edc BooleanOperator -> RelationalOperator 2022-07-30 12:08:21 +10:00
Astrash c2902cc549 Add paralithic as layered gen dependency 2022-07-30 12:01:10 +10:00
Astrash 9a171b0cdb Implement dot product layer palette 2022-07-30 12:00:54 +10:00
Astrash 596c84ab10 Forgot signature change in chunk generator 2022-07-30 11:59:15 +10:00
Astrash d9bd9135de Add point sets to layered gen 2022-07-30 11:58:59 +10:00
Astrash 50397a4a6b Add loaders for vector classes 2022-07-30 11:53:00 +10:00
Astrash 55e024dab0 Change layer signatures 2022-07-30 11:52:09 +10:00
Astrash c733c21e3c Implement biome defined layer samplers 2022-07-18 12:00:28 +10:00
Astrash 7baace047b Change layer class method signatures 2022-07-18 11:59:25 +10:00
Astrash 237b897146 Rename predicates key to tests 2022-07-17 20:36:26 +10:00
Astrash 0b057c5a74 Add platform air layer palette 2022-07-17 20:36:12 +10:00
Astrash fea7d7a4fd Implement sampler operators + sampler list predicate 2022-07-17 20:35:05 +10:00
Astrash 4d31fda79f Implement layer palette groups 2022-07-16 20:11:17 +10:00
Astrash edcba9707d Implement biome defined layer palettes 2022-07-16 18:56:30 +10:00
Astrash b57b71baa7 Replace BLOCK layer palette with PALETTE 2022-07-16 17:17:18 +10:00
Astrash 698725c921 Implement layer samplers 2022-07-16 17:03:28 +10:00
Astrash 809a6422a1 Rename some keys 2022-07-16 16:36:45 +10:00
Astrash 11044b6589 Store palettes and predicates in registries 2022-07-16 16:28:57 +10:00
Astrash 2a9d94094c Finish initial layered generator implementation 2022-07-12 13:15:27 +10:00
Astrash e831f85d45 Partial layered generator implementation 2022-07-12 09:47:29 +10:00
172 changed files with 3279 additions and 405 deletions
+4 -4
View File
@@ -17,16 +17,16 @@ jobs:
contents: read
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
- uses: actions/checkout@v4.2.2
- name: Set up JDK 21
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
uses: actions/setup-java@v4.7.1
with:
java-version: '21'
distribution: 'temurin'
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
settings-path: ${{ github.workspace }} # location for the settings.xml file
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
- uses: burrunan/gradle-cache-action@v3.0.1
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
+5 -5
View File
@@ -16,11 +16,11 @@ repositories {
dependencies {
//TODO Allow pulling from Versions.kt
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.6")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.16")
implementation("org.ow2.asm", "asm", "9.7")
implementation("org.ow2.asm", "asm-tree", "9.7")
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "2.0.0-beta.17")
implementation("org.ow2.asm", "asm", "9.8")
implementation("org.ow2.asm", "asm-tree", "9.8")
implementation("com.dfsek.tectonic", "common", "4.2.1")
implementation("org.yaml", "snakeyaml", "2.3")
implementation("org.yaml", "snakeyaml", "2.4")
}
+2 -2
View File
@@ -69,8 +69,8 @@ fun Project.configureDependencies() {
}
dependencies {
testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit)
testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit)
testImplementation("org.junit.jupiter", "junit-jupiter", Versions.Libraries.Internal.junit)
"testRuntimeOnly"("org.junit.platform", "junit-platform-launcher")
compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations)
compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava)
+31 -31
View File
@@ -1,36 +1,36 @@
object Versions {
object Terra {
const val overworldConfig = "v1.3.4"
const val overworldConfig = "v1.5.1"
}
object Libraries {
const val tectonic = "4.2.1"
const val paralithic = "1.0.3-SNAPSHOT"
const val paralithic = "1.0.3"
const val strata = "1.3.2"
const val seismic = "0.3.2-SNAPSHOT"
const val seismic = "0.3.4"
const val cloud = "2.0.0"
const val caffeine = "3.1.8"
const val slf4j = "2.0.16"
const val caffeine = "3.2.0"
const val slf4j = "2.0.17"
object Internal {
const val shadow = "8.3.3"
const val apacheText = "1.12.0"
const val apacheIO = "2.17.0"
const val guava = "33.3.1-jre"
const val asm = "9.7.1"
const val snakeYml = "2.3"
const val jetBrainsAnnotations = "26.0.1"
const val junit = "5.11.3"
const val shadow = "8.3.6"
const val apacheText = "1.13.1"
const val apacheIO = "2.19.0"
const val guava = "33.4.8-jre"
const val asm = "9.8"
const val snakeYml = "2.4"
const val jetBrainsAnnotations = "26.0.2"
const val junit = "5.13.0"
const val nbt = "6.1"
}
}
object Fabric {
const val fabricAPI = "0.118.0+${Mod.minecraft}"
const val cloud = "2.0.0-beta.9"
const val fabricAPI = "0.125.3+${Mod.minecraft}"
const val cloud = "2.0.0-beta.10"
}
//
// object Quilt {
@@ -39,13 +39,13 @@ object Versions {
// }
object Mod {
const val mixin = "0.15.3+mixin.0.8.7"
const val mixin = "0.15.5+mixin.0.8.7"
const val minecraft = "1.21.4"
const val yarn = "$minecraft+build.8"
const val fabricLoader = "0.16.10"
const val minecraft = "1.21.5"
const val yarn = "$minecraft+build.1"
const val fabricLoader = "0.16.14"
const val architecuryLoom = "1.9.428"
const val architecuryLoom = "1.10.431"
const val architecturyPlugin = "3.4.161"
}
@@ -56,14 +56,14 @@ object Versions {
// }
object Bukkit {
const val minecraft = "1.21.4"
const val paperBuild = "$minecraft-R0.1-20250317.101324-208"
const val minecraft = "1.21.5-R0.1"
const val paperBuild = "$minecraft-20250529.121722-14"
const val paper = paperBuild
const val paperLib = "1.0.8"
const val reflectionRemapper = "0.1.1"
const val paperDevBundle = paperBuild
const val reflectionRemapper = "0.1.2"
const val paperDevBundle = "$minecraft-20250529.121722-99"
const val runPaper = "2.3.1"
const val paperWeight = "2.0.0-beta.16"
const val paperWeight = "2.0.0-beta.17"
const val cloud = "2.0.0-beta.10"
}
@@ -75,18 +75,18 @@ object Versions {
// }
//
object CLI {
const val logback = "1.5.8"
const val picocli = "4.7.6"
const val logback = "1.5.18"
const val picocli = "4.7.7"
}
object Allay {
const val api = "0.2.0"
const val gson = "2.12.1"
const val api = "0.4.1"
const val gson = "2.13.1"
const val mappings = "3626653"
const val mappingsGenerator = "366618e"
}
object Minestom {
const val minestom = "187931e50b"
const val minestom = "1_21_5-4d91778331"
}
}
@@ -83,8 +83,8 @@ public class PipelineBiomeProvider implements BiomeProvider {
public Biome getBiome(int x, int z, long seed) {
x += mutator.getSample(seed + 1, x, z) * noiseAmp;
z += mutator.getSample(seed + 2, x, z) * noiseAmp;
x += (int) (mutator.getSample(seed + 1, x, z) * noiseAmp);
z += (int) (mutator.getSample(seed + 2, x, z) * noiseAmp);
x /= resolution;
z /= resolution;
@@ -2,6 +2,8 @@ package com.dfsek.terra.addons.biome.pipeline.pipeline;
import java.util.List;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
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;
@@ -98,7 +100,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 (int) Math.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
return FloatingPointFunctions.ceil((double) finalGridOrigin / initialGridInterval) * initialGridInterval;
}
private static int calculateFinalGridOrigin(int totalExpanderCount, List<Stage> stages) {
@@ -0,0 +1,11 @@
version = version("0.1.0")
dependencies {
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
api("com.dfsek", "paralithic", Versions.Libraries.paralithic)
}
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
relocate("net.jafama", "com.dfsek.terra.addons.chunkgenerator.lib.jafama")
relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.chunkgenerator.lib.paralithic")
}
@@ -0,0 +1,177 @@
package com.dfsek.terra.addons.chunkgenerator;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.sampler.ElevationLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPalettePackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerPredicatePackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerResolverPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pack.LayerSamplerPackConfigTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomeDefinedLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.DotProductLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.PlatformAirLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.palette.SimpleLayerPaletteTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.AdjacentPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.SimplePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CubePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.CuboidPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric.SphericalPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.DifferencePointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.ExpressionFilterPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.IntersectionPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.pointset.operative.UnionPointSetTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.BelowLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.RangeLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.predicate.SamplerListLayerPredicateTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.resolve.PaletteLayerResolverTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.resolve.PredicateLayerResolverTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.sampler.BiomeDefinedLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.config.sampler.DensityLayerSamplerTemplate;
import com.dfsek.terra.addons.chunkgenerator.generation.LayeredChunkGenerator;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;
public class LayeredChunkGeneratorAddon implements AddonInitializer {
private static final Logger logger = LoggerFactory.getLogger( LayeredChunkGeneratorAddon.class);
public static final TypeKey<Supplier<ObjectTemplate<PointSet>>> POINT_SET_TYPE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<LayerSampler>>> LAYER_SAMPLER_TYPE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<InstanceWrapper<LayerSampler>> LAYER_SAMPLER_TOKEN = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<LayerPalette>>> LAYER_PALETTE_TYPE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<InstanceWrapper<LayerPalette>> LAYER_PALETTE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<LayerPredicate>>> LAYER_PREDICATE_TYPE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<InstanceWrapper<LayerPredicate>> LAYER_PREDICATE_TOKEN = new TypeKey<>() {
};
public static final TypeKey<Supplier<ObjectTemplate<LayerResolver>>> LAYER_RESOLVER_TYPE_TOKEN = new TypeKey<>() {
};
@Inject
private Platform platform;
@Inject
private BaseAddon addon;
@Override
public void initialize() {
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigPackPreLoadEvent.class)
.priority(1000)
.then(event -> {
event.getPack().applyLoader(RelationalOperator.class,
(type, o, loader, depthTracker) -> RelationalOperator.valueOf((String) o));
CheckedRegistry<Supplier<ObjectTemplate<PointSet>>> pointSetTypeRegistry = event.getPack().getOrCreateRegistry(
POINT_SET_TYPE_TOKEN);
pointSetTypeRegistry.register(addon.key("LIST"), SimplePointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("ADJACENT"), AdjacentPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("SPHERE"), SphericalPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("CUBOID"), CuboidPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("CUBE"), CubePointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("UNION"), UnionPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("INTERSECTION"), IntersectionPointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("DIFFERENCE"), DifferencePointSetTemplate::new);
pointSetTypeRegistry.register(addon.key("EXPRESSION"), ExpressionFilterPointSetTemplate::new);
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerSampler>>> samplerTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TYPE_TOKEN);
CheckedRegistry<InstanceWrapper<LayerSampler>> samplerRegistry = event.getPack().getOrCreateRegistry(LAYER_SAMPLER_TOKEN);
samplerTypeRegistry.register(addon.key("DENSITY"), DensityLayerSamplerTemplate::new);
samplerTypeRegistry.register(addon.key("ELEVATION"), ElevationLayerSamplerTemplate::new);
samplerTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerSamplerTemplate::new);
event.loadTemplate(new LayerSamplerPackConfigTemplate()).getSamplers().forEach((key, sampler) -> {
samplerRegistry.register(addon.key(key), new InstanceWrapper<>(sampler));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPredicate>>> predicateTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TYPE_TOKEN);
predicateTypeRegistry.register(addon.key("BELOW"), BelowLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("RANGE"), RangeLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER"), SamplerLayerPredicateTemplate::new);
predicateTypeRegistry.register(addon.key("SAMPLER_POINTS"), SamplerListLayerPredicateTemplate::new);
CheckedRegistry<InstanceWrapper<LayerPredicate>> predicateRegistry = event.getPack().getOrCreateRegistry(LAYER_PREDICATE_TOKEN);
event.loadTemplate(new LayerPredicatePackConfigTemplate()).getPredicates().forEach((key, predicate) -> {
predicateRegistry.register(addon.key(key), new InstanceWrapper<>(predicate));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerPalette>>> paletteTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TYPE_TOKEN);
paletteTypeRegistry.register(addon.key("PALETTE"), SimpleLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("BIOME_DEFINED"), BiomeDefinedLayerPaletteTemplate::new);
paletteTypeRegistry.register(addon.key("AIR"), () -> new PlatformAirLayerPaletteTemplate(platform));
paletteTypeRegistry.register(addon.key("SURFACE_NORMAL"), DotProductLayerPaletteTemplate::new);
event.getPack().applyLoader(LayerPalette.Group.class, new LayerPalette.Group.Loader(event.getPack()));
CheckedRegistry<InstanceWrapper<LayerPalette>> paletteRegistry = event.getPack().getOrCreateRegistry(LAYER_PALETTE_TOKEN);
event.loadTemplate(new LayerPalettePackConfigTemplate()).getPalettes().forEach((key, palette) -> {
paletteRegistry.register(addon.key(key), new InstanceWrapper<>(palette));
});
})
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<LayerResolver>>> resolverTypeRegistry = event.getPack().getOrCreateRegistry(LAYER_RESOLVER_TYPE_TOKEN);
resolverTypeRegistry.register(addon.key("TEST"), PredicateLayerResolverTemplate::new);
resolverTypeRegistry.register(addon.key("LAYER"), PaletteLayerResolverTemplate::new);
LayerResolver resolver = event.loadTemplate(new LayerResolverPackConfigTemplate()).getResolver();
event.getPack()
.getOrCreateRegistry(ChunkGeneratorProvider.class)
.register(addon.key("LAYERED"),
pack -> new LayeredChunkGenerator(platform, resolver));
})
.failThrough();
platform.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(addon, ConfigurationLoadEvent.class)
.priority(1000)
.then(BiomeDefinedLayerPalette.injectLayerPalettes)
.then(BiomeDefinedLayerSampler.injectLayerSamplers);
}
}
@@ -0,0 +1,72 @@
package com.dfsek.terra.addons.chunkgenerator.api;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.properties.Properties;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public abstract class LayerPalette {
private final Group group;
private final boolean resetsGroup;
protected LayerPalette(Group group, boolean resetsGroup) {
this.group = group;
this.resetsGroup = resetsGroup;
}
public abstract Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);
public final Group getGroup() {
return group;
}
public final boolean resetsGroup() {
return resetsGroup;
}
public static class Group {
public static Group NO_GROUP = new Group();
private Group() {}
public static Group get(String string, ConfigPack pack) {
if (!pack.getContext().has(Holder.class)) {
pack.getContext().put(new Holder(new HashMap<>()));
}
return pack.getContext().get(Holder.class).groups.computeIfAbsent(string, s -> new Group());
}
private record Holder(Map<String, Group> groups) implements Properties {}
public static class Loader implements TypeLoader<Group> {
private final ConfigPack pack;
public Loader(ConfigPack pack) {
this.pack = pack;
}
@Override
public Group load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
String groupName = (String) o;
return Group.get(groupName, pack);
}
}
}
}
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public interface LayerPredicate {
boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider);
}
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public interface LayerResolver {
LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.addons.chunkgenerator.api;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public interface LayerSampler {
double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider);
ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider);
double getBlendWeight();
}
@@ -0,0 +1,9 @@
package com.dfsek.terra.addons.chunkgenerator.api.chunk;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public interface ChunkLayerSampler {
double sample(int fmX, int y, int fmZ);
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.api.config.meta.Meta;
public class LayerPalettePackConfigTemplate implements ConfigTemplate {
@Value("generation.layers")
private @Meta Map<String, LayerPalette> palettes;
public Map<String, LayerPalette> getPalettes() {
return palettes;
}
}
@@ -0,0 +1,24 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.api.config.meta.Meta;
public class LayerPredicatePackConfigTemplate implements ConfigTemplate {
@Value("generation.tests")
@Default
private @Meta Map<String, LayerPredicate> predicates = new LinkedHashMap<>();
public Map<String, LayerPredicate> getPredicates() {
return predicates;
}
}
@@ -0,0 +1,18 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.api.config.meta.Meta;
public class LayerResolverPackConfigTemplate implements ConfigTemplate {
@Value("generation.resolver")
private @Meta LayerResolver resolver;
public LayerResolver getResolver() {
return resolver;
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pack;
import com.dfsek.tectonic.api.config.template.ConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.api.config.meta.Meta;
public class LayerSamplerPackConfigTemplate implements ConfigTemplate {
@Value("generation.samplers")
private @Meta Map<String, LayerSampler> samplers;
public Map<String, LayerSampler> getSamplers() {
return samplers;
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.BiomeDefinedLayerPalette;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class BiomeDefinedLayerPaletteTemplate extends LayerPaletteTemplate {
@Value("default")
@Default
private Palette defaultPalette = null;
@Override
public LayerPalette get() {
return new BiomeDefinedLayerPalette(group, resetsGroup, defaultPalette);
}
}
@@ -0,0 +1,44 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.DotProductLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet;
import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class DotProductLayerPaletteTemplate extends LayerPaletteTemplate {
@Value("normal.approximation-points")
@Default
private PointSet normalApproximationPoints = new AdjacentPointSet();
@Value("normal.direction")
@Default
private Vector3 direction = Vector3.of(0, 1, 0);
@Value("normal.sampler")
private InstanceWrapper<LayerSampler> sampler;
@Value("palettes")
private Map<String, Palette> palettes;
@Override
public LayerPalette get() {
Map<Double, Palette> paletteMap = new HashMap<>();
palettes.forEach((s, p) -> {
paletteMap.put(Double.parseDouble(s), p);
});
return new DotProductLayerPalette(group, resetsGroup, normalApproximationPoints, new DoubleNavigableHolder<>(paletteMap), sampler.get(), direction);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
public abstract class LayerPaletteTemplate implements ObjectTemplate<LayerPalette> {
@Value("group")
@Default
protected LayerPalette.Group group = LayerPalette.Group.NO_GROUP;
@Value("resets-group")
@Default
protected boolean resetsGroup = false;
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette;
import com.dfsek.terra.addons.chunkgenerator.palette.SingletonPalette;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState;
public class PlatformAirLayerPaletteTemplate extends LayerPaletteTemplate {
private BlockState air;
public PlatformAirLayerPaletteTemplate(Platform platform) {
this.air = platform.getWorldHandle().air();
}
@Override
public LayerPalette get() {
return new SimpleLayerPalette(group, resetsGroup, new SingletonPalette(air));
}
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.addons.chunkgenerator.config.palette;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.layer.palette.SimpleLayerPalette;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class SimpleLayerPaletteTemplate extends LayerPaletteTemplate {
@Value("palette")
private Palette palette;
@Override
public LayerPalette get() {
return new SimpleLayerPalette(group, resetsGroup, palette);
}
}
@@ -0,0 +1,15 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.AdjacentPointSet;
public class AdjacentPointSetTemplate implements ObjectTemplate<PointSet> {
@Override
public PointSet get() {
return new AdjacentPointSet();
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.Set;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.SimplePointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class SimplePointSetTemplate implements ObjectTemplate<PointSet> {
@Value("points")
private Set<Vector3Int> list;
@Override
public PointSet get() {
return new SimplePointSet(list);
}
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet;
public class CubePointSetTemplate implements ObjectTemplate<PointSet> {
@Value("size")
private int size;
@Override
public PointSet get() {
return new CuboidPointSet(-size, -size, -size, size, size, size);
}
}
@@ -0,0 +1,25 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.CuboidPointSet;
public class CuboidPointSetTemplate implements ObjectTemplate<PointSet> {
@Value("size.x")
private int xSize;
@Value("size.y")
private int ySize;
@Value("size.z")
private int zSize;
@Override
public PointSet get() {
return new CuboidPointSet(-xSize, -ySize, -zSize, xSize, ySize, zSize);
}
}
@@ -0,0 +1,19 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.generative.geometric;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric.SphericalPointSet;
public class SphericalPointSetTemplate implements ObjectTemplate<PointSet> {
@Value("radius")
private double radius;
@Override
public PointSet get() {
return new SphericalPointSet(radius);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.DifferencePointSet;
public class DifferencePointSetTemplate implements ObjectTemplate<PointSet> {
@Value("point-sets")
private List<PointSet> set;
@Override
public PointSet get() {
return new DifferencePointSet(set);
}
}
@@ -0,0 +1,27 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.ExpressionFilterPointSet;
public class ExpressionFilterPointSetTemplate implements ObjectTemplate<PointSet> {
@Value("point-set")
private PointSet set;
@Value("expression")
private String expression;
@Override
public PointSet get() {
try {
return new ExpressionFilterPointSet(set, expression);
} catch(ParseException e) {
throw new RuntimeException("Failed to parse expression.", e);
}
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.IntersectionPointSet;
public class IntersectionPointSetTemplate implements ObjectTemplate<PointSet> {
@Value("point-sets")
private List<PointSet> sets;
@Override
public PointSet get() {
return new IntersectionPointSet(sets);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.pointset.operative;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.operative.UnionPointSet;
public class UnionPointSetTemplate implements ObjectTemplate<PointSet> {
@Value("point-sets")
private List<PointSet> sets;
@Override
public PointSet get() {
return new UnionPointSet(sets);
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.config.predicate;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.BelowLayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.api.config.meta.Meta;
public class BelowLayerPredicateTemplate implements ObjectTemplate<LayerPredicate> {
@Value("y")
private @Meta int y;
@Override
public LayerPredicate get() {
return new BelowLayerPredicate(y);
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.config.predicate;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.RangeLayerPredicate;
import com.dfsek.terra.api.util.range.Range;
public class RangeLayerPredicateTemplate implements ObjectTemplate<LayerPredicate> {
@Value("range")
private Range range;
@Override
public LayerPredicate get() {
return new RangeLayerPredicate(range);
}
}
@@ -0,0 +1,32 @@
package com.dfsek.terra.addons.chunkgenerator.config.predicate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerLayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.api.config.meta.Meta;
public class SamplerLayerPredicateTemplate implements ObjectTemplate<LayerPredicate> {
@Value("sampler")
private @Meta InstanceWrapper<LayerSampler> sampler;
@Value("threshold")
@Default
private double threshold = 0;
@Value("operator")
@Default
private RelationalOperator operator = RelationalOperator.GreaterThan;
@Override
public LayerPredicate get() {
return new SamplerLayerPredicate(sampler.get(), operator, threshold);
}
}
@@ -0,0 +1,36 @@
package com.dfsek.terra.addons.chunkgenerator.config.predicate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.addons.chunkgenerator.layer.predicate.SamplerListLayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.api.config.meta.Meta;
public class SamplerListLayerPredicateTemplate implements ObjectTemplate<LayerPredicate> {
@Value("sampler")
private @Meta InstanceWrapper<LayerSampler> sampler;
@Value("point-set")
private PointSet points;
@Value("threshold")
@Default
private double defaultThreshold = 0;
@Value("operator")
@Default
private RelationalOperator defaultOperator = RelationalOperator.GreaterThan;
@Override
public LayerPredicate get() {
return new SamplerListLayerPredicate(sampler.get(), defaultThreshold, defaultOperator, points);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.resolve;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PaletteLayerResolver;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
public class PaletteLayerResolverTemplate implements ObjectTemplate<LayerResolver> {
@Value("layer")
private InstanceWrapper<LayerPalette> palette;
@Override
public LayerResolver get() {
return new PaletteLayerResolver(palette.get());
}
}
@@ -0,0 +1,28 @@
package com.dfsek.terra.addons.chunkgenerator.config.resolve;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.addons.chunkgenerator.layer.resolve.PredicateLayerResolver;
import com.dfsek.terra.addons.chunkgenerator.util.InstanceWrapper;
import com.dfsek.terra.api.config.meta.Meta;
public class PredicateLayerResolverTemplate implements ObjectTemplate<LayerResolver> {
@Value("if")
private @Meta InstanceWrapper<LayerPredicate> predicate;
@Value("then")
private @Meta LayerResolver trueResolver;
@Value("else")
private @Meta LayerResolver falseResolver;
@Override
public PredicateLayerResolver get() {
return new PredicateLayerResolver(predicate.get(), trueResolver, falseResolver);
}
}
@@ -0,0 +1,23 @@
package com.dfsek.terra.addons.chunkgenerator.config.sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.BiomeDefinedLayerSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.seismic.type.sampler.Sampler;
public class BiomeDefinedLayerSamplerTemplate extends LayerSamplerTemplate {
@Value("default")
@Default
private @Meta Sampler defaultSampler = null;
@Override
public LayerSampler get() {
return new BiomeDefinedLayerSampler(defaultSampler, blend);
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.config.sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.seismic.type.sampler.Sampler;
public class DensityLayerSamplerTemplate extends LayerSamplerTemplate {
@Value("sampler")
private @Meta Sampler sampler;
@Override
public LayerSampler get() {
return new DensityLayerSampler(sampler, blend);
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.config.sampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler;
import com.dfsek.terra.api.config.meta.Meta;
public class ElevationLayerSamplerTemplate extends LayerSamplerTemplate {
@Value("sampler")
private @Meta Sampler sampler;
@Override
public LayerSampler get() {
return new ElevationLayerSampler(sampler, blend);
}
}
@@ -0,0 +1,15 @@
package com.dfsek.terra.addons.chunkgenerator.config.sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.api.config.meta.Meta;
public abstract class LayerSamplerTemplate implements ObjectTemplate<LayerSampler> {
@Value("blend")
protected @Meta BlendProperties blend;
}
@@ -0,0 +1,33 @@
package com.dfsek.terra.addons.chunkgenerator.config.sampler.blend;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.tectonic.api.config.template.ValidatedConfigTemplate;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.api.config.meta.Meta;
public class BlendPropertiesConfig implements ValidatedConfigTemplate, ObjectTemplate<BlendProperties> {
@Value("density")
@Default
private @Meta int density = 3;
@Value("weight")
@Default
private @Meta double weight = 1;
@Override
public boolean validate() throws ValidationException {
return density > 1 && weight > 1 && density % 18 == 0;
}
@Override
public BlendProperties get() {
return BlendProperties.of(density, weight);
}
}
@@ -0,0 +1,90 @@
package com.dfsek.terra.addons.chunkgenerator.generation;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.util.Column;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.ChunkGenerator;
import com.dfsek.terra.api.world.chunk.generation.ProtoChunk;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public class LayeredChunkGenerator implements ChunkGenerator {
private final Platform platform;
private final LayerResolver resolver;
public LayeredChunkGenerator(Platform platform, LayerResolver resolver) {
this.platform = platform;
this.resolver = resolver;
}
@Override
public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world, @NotNull BiomeProvider biomeProvider,
int chunkX, int chunkZ) {
platform.getProfiler().push("chunk_base_layered");
int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4);
long seed = world.getSeed();
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
int cx = xOrig + x;
int cz = zOrig + z;
int paletteLevel = 0;
LayerPalette previousLayerPalette = null;
Column<Biome> biomeColumn = biomeProvider.getColumn(cx, cz, world);
for(int y = world.getMaxHeight() - 1; y >= world.getMinHeight(); y--) {
Biome biome = biomeColumn.get(y);
LayerPalette layerPalette = resolver.resolve(cx, y, cz, world, biomeProvider);
if (previousLayerPalette == layerPalette) {
paletteLevel++;
} else if (layerPalette.resetsGroup()) {
paletteLevel = 0;
} else if (previousLayerPalette != null && layerPalette.getGroup() == previousLayerPalette.getGroup()) {
paletteLevel++;
} else {
paletteLevel = 0;
}
previousLayerPalette = layerPalette;
chunk.setBlock(cx, y, cz, layerPalette.get(cx, y, cz, world, biomeProvider)
.get(paletteLevel, cx, y, cz, seed));
}
}
}
platform.getProfiler().pop("chunk_base_layered");
}
@Override
public BlockState getBlock(WorldProperties world, int x, int y, int z, BiomeProvider biomeProvider) {
long seed = world.getSeed();
Biome biome = biomeProvider.getBiome(x, y, z, seed);
int layer = 0; // Default to layer 0 for now
return resolver.resolve(x, y, z, world, biomeProvider)
.get(x, y, z, world, biomeProvider)
.get(layer, x, y, z, seed);
}
@Override
public Palette getPalette(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
long seed = world.getSeed();
Biome biome = biomeProvider.getBiome(x, y, z, seed);
return resolver.resolve(x, y, z, world, biomeProvider)
.get(x, y, z, world, biomeProvider);
}
}
@@ -0,0 +1,70 @@
package com.dfsek.terra.addons.chunkgenerator.layer.palette;
import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate;
import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
import com.dfsek.terra.api.properties.Properties;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public class BiomeDefinedLayerPalette extends LayerPalette {
private final Palette defaultPalette;
public BiomeDefinedLayerPalette(Group group, boolean resetsGroup, Palette defaultPalette) {
super(group, resetsGroup);
this.defaultPalette = defaultPalette;
}
@Override
public Palette get(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) {
return biomeProvider.getBiome(x, y, z, worldProperties.getSeed()).getContext().get(BiomeLayerPalettes.class).palettes().get(this);
}
public Optional<Palette> getDefaultPalette() {
return Optional.ofNullable(defaultPalette);
}
public static Consumer<ConfigurationLoadEvent> injectLayerPalettes = event -> {
if(event.is(Biome.class)) {
Map<BiomeDefinedLayerPalette, String> paletteFields = new HashMap<>();
DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder();
event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_PALETTE_TOKEN).forEach((registryKey, registryEntry) -> {
LayerPalette layerPalette = registryEntry.get();
// Add template value for each BiomeDefinedLayerPalette
if (layerPalette instanceof BiomeDefinedLayerPalette biomeLayerPalette) {
String id = registryKey.getID();
String fieldName = id + "LayerPalette";
paletteFields.put(biomeLayerPalette, fieldName);
DynamicValue.Builder<Palette> value = DynamicValue.builder("generation.layers." + id, Palette.class);
biomeLayerPalette.getDefaultPalette().ifPresent(value::setDefault);
templateBuilder.value(fieldName, value.build());
}
});
DynamicTemplate layerPaletteBiomeTemplate = event.load(templateBuilder.build());
Map<BiomeDefinedLayerPalette, Palette> paletteMap = paletteFields.entrySet().stream().collect(
Collectors.toMap(Entry::getKey, entry -> layerPaletteBiomeTemplate.get(entry.getValue(), Palette.class)));
event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerPalettes(paletteMap));
}
};
public record BiomeLayerPalettes(Map<BiomeDefinedLayerPalette, Palette> palettes) implements Properties {
}
}
@@ -0,0 +1,43 @@
package com.dfsek.terra.addons.chunkgenerator.layer.palette;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.terra.addons.chunkgenerator.palette.DoubleNavigableHolder;
import com.dfsek.seismic.type.vector.Vector3;
import com.dfsek.seismic.type.vector.Vector3Int;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public class DotProductLayerPalette extends LayerPalette {
private static final Logger logger = LoggerFactory.getLogger(DotProductLayerPalette.class);
private final DoubleNavigableHolder<Palette> palettes;
private final Vector3Int[] samplePoints;
private final LayerSampler sampler;
private final Vector3 direction;
public DotProductLayerPalette(Group group, boolean resetsGroup,
PointSet points, DoubleNavigableHolder<Palette> palettes, LayerSampler sampler, Vector3 direction) {
super(group, resetsGroup);
this.palettes = palettes;
this.sampler = sampler;
this.direction = direction;
this.samplePoints = points.toArray();
}
@Override
public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
Vector3.Mutable surfaceNormalApproximation = Vector3.Mutable.of(0, 0, 0);
for(Vector3Int point : samplePoints) {
double scalar = -sampler.sample(x+point.getX(), y+point.getY(), z+point.getZ(), world, biomeProvider);
surfaceNormalApproximation.add(point.toFloat().mutable().mulScalar(scalar));
}
return palettes.get(direction.dot(surfaceNormalApproximation.normalize()));
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.addons.chunkgenerator.layer.palette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
import com.dfsek.terra.api.world.info.WorldProperties;
public class SimpleLayerPalette extends LayerPalette {
private final Palette palette;
public SimpleLayerPalette(Group group, boolean resetsGroup, Palette palette) {
super(group, resetsGroup);
this.palette = palette;
}
@Override
public Palette get(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return palette;
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.layer.predicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class BelowLayerPredicate implements LayerPredicate {
private final int y;
public BelowLayerPredicate(int y) {
this.y = y;
}
@Override
public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) {
return y < this.y;
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.layer.predicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.api.util.range.Range;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class RangeLayerPredicate implements LayerPredicate {
private final Range range;
public RangeLayerPredicate(Range range) {
this.range = range;
}
@Override
public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) {
return range.isInRange(y);
}
}
@@ -0,0 +1,29 @@
package com.dfsek.terra.addons.chunkgenerator.layer.predicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class SamplerLayerPredicate implements LayerPredicate {
private final LayerSampler sampler;
private final double threshold;
private final RelationalOperator operator;
public SamplerLayerPredicate(LayerSampler sampler, RelationalOperator operator, double threshold) {
this.sampler = sampler;
this.operator = operator;
this.threshold = threshold;
}
@Override
public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) {
return operator.test(sampler.sample(x, y, z, worldProperties, biomeProvider), threshold);
}
}
@@ -0,0 +1,33 @@
package com.dfsek.terra.addons.chunkgenerator.layer.predicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.math.RelationalOperator;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class SamplerListLayerPredicate implements LayerPredicate {
private final Vector3Int[] points;
private final RelationalOperator operator;
private final LayerSampler sampler;
private final double threshold;
public SamplerListLayerPredicate(LayerSampler sampler, double threshold, RelationalOperator operator, PointSet points) {
this.sampler = sampler;
this.threshold = threshold;
this.operator = operator;
this.points = points.toArray();
}
@Override
public boolean test(int x, int y, int z, WorldProperties worldProperties, BiomeProvider biomeProvider) {
for (Vector3Int point : points) {
if (operator.test(sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ(), worldProperties, biomeProvider), threshold)) return true;
}
return false;
}
}
@@ -0,0 +1,21 @@
package com.dfsek.terra.addons.chunkgenerator.layer.resolve;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class PaletteLayerResolver implements LayerResolver {
private final LayerPalette palette;
public PaletteLayerResolver(LayerPalette palette) {
this.palette = palette;
}
@Override
public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return palette;
}
}
@@ -0,0 +1,28 @@
package com.dfsek.terra.addons.chunkgenerator.layer.resolve;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPalette;
import com.dfsek.terra.addons.chunkgenerator.api.LayerPredicate;
import com.dfsek.terra.addons.chunkgenerator.api.LayerResolver;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class PredicateLayerResolver implements LayerResolver {
private final LayerPredicate predicate;
private final LayerResolver trueResolver;
private final LayerResolver falseResolver;
public PredicateLayerResolver(LayerPredicate predicate, LayerResolver trueResolver, LayerResolver falseResolver) {
this.predicate = predicate;
this.trueResolver = trueResolver;
this.falseResolver = falseResolver;
}
@Override
public LayerPalette resolve(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return predicate.test(x, y, z, world, biomeProvider) ? trueResolver.resolve(x, y, z, world, biomeProvider) : falseResolver.resolve(x, y, z, world, biomeProvider);
}
}
@@ -0,0 +1,90 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler;
import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate;
import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.properties.Properties;
import com.dfsek.terra.api.world.biome.Biome;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class BiomeDefinedLayerSampler implements LayerSampler {
private final Sampler defaultSampler;
private final BlendProperties blendProperties;
public BiomeDefinedLayerSampler(@Nullable Sampler defaultSampler, BlendProperties blendProperties) {
this.defaultSampler = defaultSampler;
this.blendProperties = blendProperties;
}
@Override
public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
return biomeProvider.getBiome(x, y, z, world.getSeed())
.getContext()
.get(BiomeLayerSamplers.class)
.samplers()
.get(this)
.getSample(world.getSeed(), x, y, z);
}
@Override
public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) {
return null;
}
@Override
public double getBlendWeight() {
return blendProperties.weight();
}
private Optional<Sampler> getDefaultSampler() {
return Optional.ofNullable(defaultSampler);
}
public static Consumer<ConfigurationLoadEvent> injectLayerSamplers = event -> {
if(event.is(Biome.class)) {
Map<BiomeDefinedLayerSampler, String> samplerFields = new HashMap<>();
DynamicTemplate.Builder templateBuilder = DynamicTemplate.builder();
event.getPack().getRegistry(LayeredChunkGeneratorAddon.LAYER_SAMPLER_TOKEN).forEach((registryKey, registryEntry) -> {
LayerSampler layerSampler = registryEntry.get();
if (layerSampler instanceof BiomeDefinedLayerSampler biomeLayerSampler) {
String id = registryKey.getID();
String fieldName = id + "LayerSampler";
samplerFields.put(biomeLayerSampler, fieldName);
DynamicValue.Builder<Sampler> value = DynamicValue.builder("generation.samplers." + id, Sampler.class);
biomeLayerSampler.getDefaultSampler().ifPresent(value::setDefault);
templateBuilder.value(fieldName, value.build());
}
});
DynamicTemplate layerSamplerBiomeTemplate = event.load(templateBuilder.build());
Map<BiomeDefinedLayerSampler, Sampler> samplerMap = samplerFields.entrySet().stream().collect(
Collectors.toMap(Entry::getKey, entry -> layerSamplerBiomeTemplate.get(entry.getValue(), Sampler.class)));
event.getLoadedObject(Biome.class).getContext().put(new BiomeLayerSamplers(samplerMap));
}
};
public record BiomeLayerSamplers(Map<BiomeDefinedLayerSampler, Sampler> samplers) implements Properties {
}
}
@@ -0,0 +1,41 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.DensityChunkLayerSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class DensityLayerSampler implements LayerSampler {
private final Sampler sampler;
private final BlendProperties blendProperties;
public DensityLayerSampler(Sampler sampler, BlendProperties blendProperties) {
this.sampler = sampler;
this.blendProperties = blendProperties;
}
@Override
public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
//TODO if needed make this match chunk impl
return sampler.getSample(world.getSeed(), x, y, z);
}
@Override
public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) {
return new DensityChunkLayerSampler(chunkX, chunkZ, world, biomeProvider, this, blendProperties);
}
@Override
public double getBlendWeight() {
return blendProperties.weight();
}
}
@@ -0,0 +1,39 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.DensityChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk.ElevationChunkLayerSampler;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class ElevationLayerSampler implements LayerSampler {
private final Sampler sampler;
private final BlendProperties blendProperties;
public ElevationLayerSampler(Sampler sampler, BlendProperties blendProperties) {
this.sampler = sampler;
this.blendProperties = blendProperties;
}
@Override
public double sample(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
//TODO if needed make this match chunk impl
return sampler.getSample(world.getSeed(), x, z);
}
@Override
public ChunkLayerSampler getChunk(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider) {
return new ElevationChunkLayerSampler(chunkX, chunkZ, world, biomeProvider, this, blendProperties);
}
@Override
public double getBlendWeight() {
return blendProperties.weight();
}
}
@@ -0,0 +1,7 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend;
public record BlendProperties(int density, double weight, int extent) {
public static BlendProperties of(int density, double weight) {
return new BlendProperties(density, weight, Math.max((18 / density) + 1, 1));
}
}
@@ -0,0 +1,100 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.DensityLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class DensityChunkLayerSampler implements ChunkLayerSampler {
double[] samples;
private final int blendExtent;
private final int min;
private final int blendExtentYExtent;
private final int blendExtentMinus2;
private final int blendYExtendMinus2;
private final int blendDensity;
public DensityChunkLayerSampler(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider, DensityLayerSampler layerSampler, BlendProperties blendProperties) {
this.min = world.getMinHeight() - 1;
int worldMax = world.getMaxHeight() + 1;
blendDensity = blendProperties.density();
int blendYRange = worldMax - min + 1;
int max;
int blendYExtend;
if (blendYRange % blendDensity == 0) {
blendYExtend = blendYRange / blendDensity;
max = worldMax;
} else {
blendYExtend = (blendYRange / blendDensity) + 1;
max = worldMax + 1;
}
blendExtent = blendProperties.extent();
blendExtentYExtent = blendYExtend * blendExtent;
blendExtentMinus2 = blendExtent - 2;
blendYExtendMinus2 = blendYExtend - 2;
samples = new double[blendExtentYExtent * blendExtent];
int xOrigin = (chunkX << 4) - 1;
int zOrigin = (chunkZ << 4) - 1;
for (int x = 0; x < 18; x += blendDensity) {
for (int z = 0; z < 18; z += blendDensity) {
int cx = xOrigin + x;
int cz = zOrigin + z;
for (int y = this.min; y <= max; y++) {
int yi = y - this.min;
int index = x * blendExtentYExtent + yi * blendExtent + z;
samples[index] = layerSampler.sample(cx, y, cz, world, biomeProvider);
}
}
}
}
private double getSample(int x, int y, int z) {
int index = x * blendExtentYExtent + y * blendExtent + z;
return samples[index];
}
@Override
public double sample(int fmX, int y, int fmZ) {
double gx = (double)(fmX + 1) / blendDensity;
double gz = (double)(fmZ + 1) / blendDensity;
double gy = (double)(y - min) / blendDensity;
int x0 = Math.max(0, Math.min(blendExtentMinus2, FloatingPointFunctions.floor(gx)));
int z0 = Math.max(0, Math.min(blendExtentMinus2, FloatingPointFunctions.floor(gz)));
int y0 = Math.max(0, Math.min(blendYExtendMinus2, FloatingPointFunctions.floor(gy)));
int x1 = x0 + 1;
int z1 = z0 + 1;
int y1 = y0 + 1;
double tx = gx - x0;
double tz = gz - z0;
double ty = gy - y0;
// Fetch 8 corners
double c000 = getSample(x0, y0, z0);
double c100 = getSample(x1, y0, z0);
double c010 = getSample(x0, y1, z0);
double c110 = getSample(x1, y1, z0);
double c001 = getSample(x0, y0, z1);
double c101 = getSample(x1, y0, z1);
double c011 = getSample(x0, y1, z1);
double c111 = getSample(x1, y1, z1);
return InterpolationFunctions.triLerp(c000, c100, c010, c110, c001, c101, c011, c111, tx, ty, tz);
}
}
@@ -0,0 +1,37 @@
package com.dfsek.terra.addons.chunkgenerator.layer.sampler.chunk;
import com.dfsek.terra.addons.chunkgenerator.api.LayerSampler;
import com.dfsek.terra.addons.chunkgenerator.api.chunk.ChunkLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.ElevationLayerSampler;
import com.dfsek.terra.addons.chunkgenerator.layer.sampler.blend.BlendProperties;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
public class ElevationChunkLayerSampler implements ChunkLayerSampler {
double[] samples;
public ElevationChunkLayerSampler(int chunkX, int chunkZ, WorldProperties world, BiomeProvider biomeProvider, ElevationLayerSampler layerSampler,
BlendProperties blendProperties) {
//I see no reason to implement sparse blending here, elevation is inexpensive. If that changes, it can be easily implemented here.
samples = new double[16 * 16];
int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
int cx = xOrigin + x;
int cz = zOrigin + z;
int index = x * 16 + z;
samples[index] = layerSampler.sample(cx, 0, cz, world, biomeProvider);
}
}
}
@Override
public double sample(int fmX, int y, int fmZ) {
int index = fmX * 16 + fmZ;
return samples[index];
}
}
@@ -0,0 +1,45 @@
package com.dfsek.terra.addons.chunkgenerator.math;
import com.dfsek.terra.addons.chunkgenerator.util.DoubleBiPredicate;
public enum RelationalOperator implements DoubleBiPredicate {
GreaterThan {
@Override
public boolean test(double a, double b) {
return a > b;
}
},
GreaterThanOrEqual {
@Override
public boolean test(double a, double b) {
return a >= b;
}
},
LessThan {
@Override
public boolean test(double a, double b) {
return a < b;
}
},
LessThanOrEqual {
@Override
public boolean test(double a, double b) {
return a <= b;
}
},
Equals {
@Override
public boolean test(double a, double b) {
return a == b;
}
},
NotEquals {
@Override
public boolean test(double a, double b) {
return a != b;
}
};
public abstract boolean test(double a, double b);
}
@@ -0,0 +1,14 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset;
import java.util.function.Supplier;
import java.util.stream.Stream;
import com.dfsek.seismic.type.vector.Vector3Int;
public interface PointSet extends Supplier<Stream<Vector3Int>> {
default Vector3Int[] toArray() {
return this.get().distinct().toArray(Vector3Int[]::new);
}
}
@@ -0,0 +1,20 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class AdjacentPointSet implements PointSet {
@Override
public Stream<Vector3Int> get() {
return Stream.of(
Vector3Int.of(0, 0, -1),
Vector3Int.of(0, 0, 1),
Vector3Int.of(0, -1, 0),
Vector3Int.of(0, 1, 0),
Vector3Int.of(-1, 0, 0),
Vector3Int.of(1, 0, 0)
);
}
}
@@ -0,0 +1,22 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative;
import java.util.Set;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class SimplePointSet implements PointSet {
private final Stream<Vector3Int> points;
public SimplePointSet(Set<Vector3Int> points) {
this.points = points.stream();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,31 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class CuboidPointSet implements PointSet {
private final Stream<Vector3Int> points;
public CuboidPointSet(int x1, int y1, int z1, int x2, int y2, int z2) {
Set<Vector3Int> points = new HashSet<>();
for (int x = x1; x <= x2; x = x + 1) {
for (int y = y1; y <= y2; y = y + 1) {
for (int z = z1; z <= z2; z = z + 1) {
points.add(Vector3Int.of(x, y, z));
}
}
}
this.points = points.stream();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,36 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.generative.geometric;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.type.DistanceFunction;
public class SphericalPointSet implements PointSet {
private final Stream<Vector3Int> points;
public SphericalPointSet(double radius) {
Stream.Builder<Vector3Int> streamBuilder = Stream.builder();
int roundedRadius = FloatingPointFunctions.ceil(radius);
for(int x = -roundedRadius; x <= roundedRadius; x++) {
for(int y = -roundedRadius; y <= roundedRadius; y++) {
for(int z = -roundedRadius; z <= roundedRadius; z++) {
Vector3Int pos = Vector3Int.of(x, y, z);
double length = pos.toFloat().length(DistanceFunction.Euclidean);
if (length == 0) continue;
if (length > radius) continue;
streamBuilder.add(pos);
}
}
}
this.points = streamBuilder.build();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,29 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class DifferencePointSet implements PointSet {
private final Stream<Vector3Int> points;
public DifferencePointSet(List<PointSet> sets) {
points = sets.stream()
.map(PointSet::get)
.map(s -> s.collect(Collectors.toSet()))
.reduce(Sets::difference).orElse(Collections.emptySet())
.stream();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,32 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class ExpressionFilterPointSet implements PointSet {
private final Stream<Vector3Int> points;
public ExpressionFilterPointSet(PointSet set, String eq) throws ParseException {
Parser parser = new Parser();
Scope scope = new Scope();
scope.addInvocationVariable("x");
scope.addInvocationVariable("y");
scope.addInvocationVariable("z");
Expression expression = parser.parse(eq, scope);
this.points = set.get().filter(v -> expression.evaluate(v.getX(), v.getY(), v.getZ()) == 1);
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,29 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class IntersectionPointSet implements PointSet {
private final Stream<Vector3Int> points;
public IntersectionPointSet(List<PointSet> sets) {
points = sets.stream()
.map(PointSet::get)
.map(s -> s.collect(Collectors.toSet()))
.reduce(Sets::intersection).orElse(Collections.emptySet())
.stream();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,29 @@
package com.dfsek.terra.addons.chunkgenerator.math.pointset.operative;
import com.google.common.collect.Sets;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.dfsek.terra.addons.chunkgenerator.math.pointset.PointSet;
import com.dfsek.seismic.type.vector.Vector3Int;
public class UnionPointSet implements PointSet {
private final Stream<Vector3Int> points;
public UnionPointSet(List<PointSet> sets) {
points = sets.stream()
.map(PointSet::get)
.map(s -> s.collect(Collectors.toSet()))
.reduce(Sets::union).orElse(Collections.emptySet())
.stream();
}
@Override
public Stream<Vector3Int> get() {
return points;
}
}
@@ -0,0 +1,34 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
public class DoubleNavigableHolder<T> {
private final NavigableMap<Double, T> map;
public DoubleNavigableHolder(Map<Double, T> inputMap) {
NavigableMap<Double, T> map = new TreeMap<>(inputMap);
map.put(Double.MAX_VALUE, map.lastEntry().getValue());
this.map = map;
}
public T get(double threshold) {
return map.ceilingEntry(threshold).getValue();
}
enum Method {
CEILING,
FLOOR,
CLOSEST
}
public class Single extends DoubleNavigableHolder<T> {
public Single(Map<Double, T> inputMap) {
super(inputMap);
}
}
}
@@ -0,0 +1,18 @@
package com.dfsek.terra.addons.chunkgenerator.palette;
import com.dfsek.terra.api.block.state.BlockState;
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
public class SingletonPalette implements Palette {
private final BlockState blockState;
public SingletonPalette(BlockState blockState) {
this.blockState = blockState;
}
@Override
public BlockState get(int layer, double x, double y, double z, long seed) {
return blockState;
}
}
@@ -0,0 +1,6 @@
package com.dfsek.terra.addons.chunkgenerator.util;
@FunctionalInterface
public interface DoubleBiPredicate {
boolean test(double a, double b);
}
@@ -0,0 +1,12 @@
package com.dfsek.terra.addons.chunkgenerator.util;
import java.util.function.Supplier;
public record InstanceWrapper<T>(T instance) implements Supplier<T> {
@Override
public T get() {
return instance;
}
}
@@ -0,0 +1,12 @@
schema-version: 1
contributors:
- Terra contributors
id: chunk-generator-layered
version: @VERSION@
entrypoints:
- "com.dfsek.terra.addons.chunkgenerator.LayeredChunkGeneratorAddon"
website:
issues: https://github.com/PolyhedralDev/Terra/issues
source: https://github.com/PolyhedralDev/Terra
docs: https://terra.polydev.org
license: MIT License
@@ -1,5 +1,6 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
@@ -28,8 +29,8 @@ public class LazilyEvaluatedInterpolator {
PropertyKey<BiomeNoiseProperties> noisePropertiesKey, int min, int horizontalRes, int verticalRes,
long seed) {
this.noisePropertiesKey = noisePropertiesKey;
int hSamples = (int) Math.ceil(16.0 / horizontalRes);
int vSamples = (int) Math.ceil((double) (max - min) / verticalRes);
int hSamples = FloatingPointFunctions.ceil(16.0 / horizontalRes);
int vSamples = FloatingPointFunctions.ceil((double) (max - min) / verticalRes);
this.zMul = (hSamples + 1);
this.yMul = zMul * zMul;
samples = new Double[yMul * (vSamples + 1)];
@@ -7,6 +7,8 @@
package com.dfsek.terra.addons.chunkgenerator.generation.math.samplers;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ChunkInterpolator;
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.ElevationInterpolator;
@@ -26,7 +28,7 @@ public class Sampler3D {
}
public double sample(double x, double y, double z) {
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation((int) Math.round(x), (int) Math.round(z));
return interpolator.getNoise(x, y, z) + elevationInterpolator.getElevation(FloatingPointFunctions.round(x), FloatingPointFunctions.round(z));
}
public double sample(int x, int y, int z) {
@@ -11,6 +11,7 @@ import java.util.BitSet;
import java.util.Map;
import java.util.random.RandomGenerator;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.math.numericanalysis.interpolation.InterpolationFunctions;
import com.dfsek.seismic.math.trigonometry.TrigonometryFunctions;
import com.dfsek.seismic.type.Rotation;
@@ -104,7 +105,7 @@ public class VanillaOre implements Structure {
}
}
int outset = (int) Math.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
int outset = FloatingPointFunctions.ceil((size / 16.0F * 2.0F + 1.0F) / 2.0F);
int x = (int) (location.getX() - Math.ceil(eighthSize) - outset);
int y = location.getY() - 2 - outset;
int z = (int) (location.getZ() - Math.ceil(eighthSize) - outset);
@@ -1,5 +1,7 @@
package com.dfsek.terra.addons.image.operator;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.image.image.Image;
import com.dfsek.terra.addons.image.util.ColorUtil;
import com.dfsek.terra.addons.image.util.ColorUtil.Channel;
@@ -232,7 +234,7 @@ public class DistanceTransform {
@Override
public double getSample(long seed, double x, double y) {
if(x < 0 || y < 0 || x >= transform.width || y >= transform.height) return transform.minDistance;
return transform.distances[(int) Math.floor(x)][(int) Math.floor(y)];
return transform.distances[FloatingPointFunctions.floor(x)][FloatingPointFunctions.floor(y)];
}
@Override
@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.type.vector.Vector2;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
@@ -45,9 +46,9 @@ public class BiomeFunction implements Function<String> {
return grid.getBiome(arguments.getOrigin().toFloat()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
.add(Vector3.of(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID();
FloatingPointFunctions.round(xz.getZ()))).immutable(), arguments.getWorld().getSeed()).getID();
}
@Override
@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -71,9 +72,9 @@ public class BlockFunction implements Function<Void> {
Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
try {
Vector3.Mutable set = Vector3.of((int) Math.round(xz.getX()),
Vector3.Mutable set = Vector3.of(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope).doubleValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat());
FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat());
BlockState current = arguments.getWorld().getBlockState(set);
if(overwrite.apply(implementationArguments, scope) || current.isAir()) {
arguments.getWorld().setBlockState(set, rot, physics.apply(implementationArguments, scope));
@@ -7,6 +7,8 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
@@ -40,9 +42,9 @@ public class CheckBlockFunction implements Function<String> {
String data = arguments.getWorld()
.getBlockState(arguments.getOrigin().toFloat()
.mutable()
.add(Vector3.of((int) Math.round(xz.getX()),
.add(Vector3.of(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope)
.doubleValue(), (int) Math.round(xz.getZ()))))
.doubleValue(), FloatingPointFunctions.round(xz.getZ()))))
.getAsString();
if(data.contains("[")) return data.substring(0, data.indexOf('[')); // Strip properties
else return data;
@@ -7,6 +7,8 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
@@ -34,9 +36,9 @@ public class GetMarkFunction implements Function<String> {
Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
String mark = arguments.getMark(Vector3.of((int) Math.floor(xz.getX()), (int) Math.floor(
String mark = arguments.getMark(Vector3.of(FloatingPointFunctions.floor(xz.getX()), FloatingPointFunctions.floor(
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ()))
FloatingPointFunctions.floor(xz.getZ()))
.mutable()
.add(arguments.getOrigin().toFloat())
.immutable());
@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,10 +65,10 @@ public class LootFunction implements Function<Void> {
registry.get(RegistryKey.parse(id))
.ifPresentOrElse(table -> {
Vector3 apply = Vector3.of((int) Math.round(xz.getX()),
Vector3 apply = Vector3.of(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope)
.intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable();
FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable();
try {
BlockEntity data = arguments.getWorld().getBlockEntity(apply);
@@ -7,6 +7,8 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.terrascript.parser.exceptions.ParseException;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
@@ -43,8 +45,8 @@ public class PullFunction implements Function<Void> {
Vector2 xz = Vector2.Mutable.of(x.apply(implementationArguments, scope).doubleValue(),
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
Vector3.Mutable mutable = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat());
Vector3.Mutable mutable = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat());
while(mutable.getY() > arguments.getWorld().getMinHeight()) {
if(!arguments.getWorld().getBlockState(mutable).isAir()) {
arguments.getWorld().setBlockState(mutable, data);
@@ -7,6 +7,8 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
@@ -37,10 +39,10 @@ public class SetMarkFunction implements Function<Void> {
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
arguments.setMark(Vector3.of((int) Math.floor(xz.getX()),
(int) Math.floor(
arguments.setMark(Vector3.of(FloatingPointFunctions.floor(xz.getX()),
FloatingPointFunctions.floor(
y.apply(implementationArguments, scope).doubleValue()),
(int) Math.floor(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(),
FloatingPointFunctions.floor(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable(),
mark.apply(implementationArguments, scope));
return null;
}
@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,8 +44,8 @@ public class StateFunction implements Function<Void> {
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
Vector3 origin = Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable();
Vector3 origin = Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).intValue(),
FloatingPointFunctions.round(xz.getZ())).mutable().add(arguments.getOrigin().toFloat()).immutable();
try {
BlockEntity state = arguments.getWorld().getBlockEntity(origin);
state.applyState(data.apply(implementationArguments, scope));
@@ -7,6 +7,7 @@
package com.dfsek.terra.addons.terrascript.script.functions;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.seismic.type.Rotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -77,17 +78,17 @@ public class StructureFunction implements Function<Boolean> {
if(script instanceof StructureScript structureScript) {
return structureScript.generate(arguments.getOrigin(),
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
.buffer(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
FloatingPointFunctions.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
}
return script.generate(arguments.getOrigin(),
arguments.getWorld()
.buffer((int) Math.round(xz.getX()),
.buffer(FloatingPointFunctions.round(xz.getX()),
y.apply(implementationArguments, scope).intValue(),
(int) Math.round(xz.getZ())),
FloatingPointFunctions.round(xz.getZ())),
arguments.getRandom(),
arguments.getRotation().rotate(rotation1));
}).orElseGet(() -> {
@@ -7,6 +7,8 @@
package com.dfsek.terra.addon.terrascript.check;
import com.dfsek.seismic.math.floatingpoint.FloatingPointFunctions;
import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D;
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider;
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
@@ -44,8 +46,8 @@ public class CheckFunction implements Function<String> {
z.apply(implementationArguments, scope).doubleValue()).rotate(arguments.getRotation());
Vector3 location = arguments.getOrigin().toFloat().mutable().add(
Vector3.of((int) Math.round(xz.getX()), y.apply(implementationArguments, scope).doubleValue(),
(int) Math.round(xz.getZ()))).immutable();
Vector3.of(FloatingPointFunctions.round(xz.getX()), y.apply(implementationArguments, scope).doubleValue(),
FloatingPointFunctions.round(xz.getZ()))).immutable();
return apply(location, arguments.getWorld());
}
+1
View File
@@ -2,6 +2,7 @@ dependencies {
compileOnlyApi("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
testImplementation("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
api("org.incendo", "cloud-core", Versions.Libraries.cloud)
@@ -20,6 +20,8 @@ package com.dfsek.terra.config;
import ca.solostudios.strata.version.Version;
import ca.solostudios.strata.version.VersionRange;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.seismic.type.vector.Vector3;
import com.dfsek.seismic.type.vector.Vector3Int;
import com.dfsek.tectonic.api.TypeRegistry;
import java.util.LinkedHashMap;
@@ -37,6 +39,8 @@ import com.dfsek.terra.config.loaders.LinkedHashMapLoader;
import com.dfsek.terra.config.loaders.MaterialSetLoader;
import com.dfsek.terra.config.loaders.ProbabilityCollectionLoader;
import com.dfsek.terra.config.loaders.RangeLoader;
import com.dfsek.terra.config.loaders.Vector3IntLoader;
import com.dfsek.terra.config.loaders.Vector3Loader;
import com.dfsek.terra.config.loaders.VersionLoader;
import com.dfsek.terra.config.loaders.VersionRangeLoader;
@@ -56,8 +60,9 @@ public class GenericLoaders implements LoaderRegistrar {
.registerLoader(MaterialSet.class, new MaterialSetLoader())
.registerLoader(VersionRange.class, new VersionRangeLoader())
.registerLoader(LinkedHashMap.class, new LinkedHashMapLoader())
.registerLoader(ParseOptions.class, ExpressionParserOptionsTemplate::new);
.registerLoader(ParseOptions.class, ExpressionParserOptionsTemplate::new)
.registerLoader(Vector3.class, new Vector3Loader())
.registerLoader(Vector3Int.class, new Vector3IntLoader());
if(platform != null) {
registry.registerLoader(BaseAddon.class, platform.getAddons())
.registerLoader(BlockType.class, (type, object, configLoader, depthTracker) -> platform
@@ -0,0 +1,31 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.List;
import java.util.Map;
import com.dfsek.seismic.type.vector.Vector3Int;
public class Vector3IntLoader implements TypeLoader<Vector3Int> {
@SuppressWarnings("unchecked")
@Override
public Vector3Int load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
if (o instanceof List) {
List<Integer> list = (List<Integer>) o;
return Vector3Int.of(list.get(0), list.get(1), list.get(2));
}
else {
Map<String, Integer> map = (Map<String, Integer>) o;
return Vector3Int.of(map.get("x"), map.get("y"), map.get("z"));
}
}
}
@@ -0,0 +1,32 @@
package com.dfsek.terra.config.loaders;
import com.dfsek.tectonic.api.depth.DepthTracker;
import com.dfsek.tectonic.api.exception.LoadException;
import com.dfsek.tectonic.api.loader.ConfigLoader;
import com.dfsek.tectonic.api.loader.type.TypeLoader;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.AnnotatedType;
import java.util.List;
import java.util.Map;
import com.dfsek.seismic.type.vector.Vector3;
public class Vector3Loader implements TypeLoader<Vector3> {
@SuppressWarnings("unchecked")
@Override
public Vector3 load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader,
DepthTracker depthTracker) throws LoadException {
if (o instanceof List) {
List<Double> list = (List<Double>) o;
return Vector3.of(list.get(0), list.get(1), list.get(2));
}
else {
Map<String, Double> map = (Map<String, Double>) o;
return Vector3.of(map.get("x"), map.get("y"), map.get("z"));
}
}
}
Binary file not shown.
+2 -2
View File
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=7a00d51fb93147819aab76024feece20b6b84e420694101f276be952e08bef03
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionSha256Sum=845952a9d6afa783db70bb3b0effaae45ae5542ca2bb7929619e8af49cb634cf
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+4 -5
View File
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -115,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@@ -206,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.
Vendored
+2 -2
View File
@@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell
@@ -16,8 +16,8 @@ import org.allaymc.api.block.type.BlockStateSafeGetter;
import org.allaymc.api.block.type.BlockTypes;
import org.allaymc.api.item.type.ItemType;
import org.allaymc.api.item.type.ItemTypeSafeGetter;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -38,7 +38,7 @@ public record AllayItemStack(ItemStack allayItemStack) implements com.dfsek.terr
allayItemStack.addEnchantment(enchantment.getType(), enchantment.getLevel());
}
allayItemStack.setLore(targetItem.getLore());
allayItemStack.setDurability(targetItem.getDurability());
allayItemStack.setDamage(targetItem.getDamage());
allayItemStack.setCustomName(targetItem.getCustomName());
allayItemStack.setMeta(targetItem.getMeta());
}
+6 -1
View File
@@ -4,7 +4,7 @@ plugins {
dependencies {
shaded(project(":platforms:bukkit:common"))
shaded(project(":platforms:bukkit:nms:v1_21_3", configuration = "reobf"))
shaded(project(":platforms:bukkit:nms:v1_21_5", configuration = "reobf"))
shaded("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
}
@@ -26,6 +26,11 @@ tasks {
minecraftVersion(Versions.Bukkit.minecraft)
dependsOn(shadowJar)
pluginJars(shadowJar.get().archiveFile)
downloadPlugins {
modrinth("viaversion", "5.3.2")
modrinth("viabackwards", "5.3.2")
}
}
}
@@ -54,10 +54,6 @@ public interface Initializer {
private static Initializer constructInitializer() {
try {
String packageVersion = NMS;
if (NMS.equals("v1_21_4")) {
packageVersion = "v1_21_3";
}
Class<?> initializerClass = Class.forName(TERRA_PACKAGE + "." + packageVersion + ".NMSInitializer");
try {
return (Initializer) initializerClass.getConstructor().newInstance();
@@ -2,7 +2,7 @@ name: "Terra"
main: "com.dfsek.terra.bukkit.TerraBukkitPlugin"
version: "@VERSION@"
load: "STARTUP"
authors: [ "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade" ]
authors: [ "dfsek", "duplexsystem", "Astrash", "solonovamax", "Sancires", "Aureus", "RogueShade", "OakLoaf" ]
website: "@WIKI@"
api-version: "1.21.1"
description: "@DESCRIPTION@"

Some files were not shown because too many files have changed in this diff Show More