mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 16:50:28 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c0aaf6c6e8 | |||
| 1ab3233cba | |||
| 59ea5a69d8 | |||
| 4ba71e9c27 | |||
| 5c7441241c |
@@ -1,47 +0,0 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
|
||||
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
|
||||
|
||||
name: Gradle Build
|
||||
|
||||
on: [ pull_request ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
server-id: github # Value of the distributionManagement/repository/id field of the pom.xml
|
||||
settings-path: ${{ github.workspace }} # location for the settings.xml file
|
||||
|
||||
- uses: burrunan/gradle-cache-action@03c71a8ba93d670980695505f48f49daf43704a6
|
||||
name: Build Terra
|
||||
with:
|
||||
# Specifies arguments for Gradle execution
|
||||
# If arguments is missing or empty, then Gradle is not executed
|
||||
arguments: build
|
||||
# arguments can be multi-line for better readability
|
||||
# arguments: |
|
||||
# --no-paralell
|
||||
# build
|
||||
# -x test
|
||||
# Gradle version to use for execution:
|
||||
# wrapper (default), current, rc, nightly, release-nightly, or
|
||||
# versions like 6.6 (see https://services.gradle.org/versions/all)
|
||||
gradle-version: wrapper
|
||||
# Properties are passed as -Pname=value
|
||||
properties: |
|
||||
kotlin.js.compiler=ir
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
@@ -249,5 +249,3 @@ nbdist/
|
||||
|
||||
platforms/**/run/**
|
||||
|
||||
#Vale Config File
|
||||
**/.vale.ini
|
||||
|
||||
+4
-5
@@ -1,8 +1,8 @@
|
||||
preRelease(true)
|
||||
|
||||
versionProjects(":common:api", version("6.6.0"))
|
||||
versionProjects(":common:implementation", version("6.6.0"))
|
||||
versionProjects(":platforms", version("6.6.0"))
|
||||
versionProjects(":common:api", version("6.5.0"))
|
||||
versionProjects(":common:implementation", version("6.5.0"))
|
||||
versionProjects(":platforms", version("6.5.0"))
|
||||
|
||||
|
||||
allprojects {
|
||||
@@ -15,7 +15,6 @@ allprojects {
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.isFork = true
|
||||
options.isIncremental = true
|
||||
options.release.set(21)
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
@@ -45,7 +44,7 @@ afterEvaluate {
|
||||
}
|
||||
project(":platforms:bukkit:common").configureDistribution()
|
||||
forSubProjects(":common:addons") {
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
|
||||
tasks.named("build") {
|
||||
finalizedBy(tasks.named("shadowJar"))
|
||||
|
||||
@@ -9,18 +9,18 @@ repositories {
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
maven("https://repo.papermc.io/repository/maven-public/") {
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
name = "PaperMC"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//TODO Allow pulling from Versions.kt
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.7.2")
|
||||
implementation("com.github.johnrengelman", "shadow", "8.1.1")
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.5.6")
|
||||
|
||||
implementation("org.ow2.asm", "asm", "9.7")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.7")
|
||||
implementation("com.dfsek.tectonic", "common", "4.2.1")
|
||||
implementation("org.yaml", "snakeyaml", "2.3")
|
||||
implementation("org.ow2.asm", "asm", "9.5")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.5")
|
||||
implementation("com.dfsek.tectonic", "common", "4.2.0")
|
||||
implementation("org.yaml", "snakeyaml", "2.2")
|
||||
}
|
||||
@@ -22,8 +22,8 @@ fun Project.configureCompilation() {
|
||||
apply<TectonicDocPlugin>()
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
|
||||
@@ -36,7 +36,7 @@ fun Project.configureDependencies() {
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
maven("https://repo.papermc.io/repository/maven-public/") {
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
name = "PaperMC"
|
||||
}
|
||||
maven("https://files.minecraftforge.net/maven/") {
|
||||
@@ -48,17 +48,17 @@ fun Project.configureDependencies() {
|
||||
maven("https://jitpack.io") {
|
||||
name = "JitPack"
|
||||
}
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
|
||||
name = "Sonatype Snapshots"
|
||||
maven("https://nexuslite.gcnt.net/repos/other/") {
|
||||
name = "GCNT"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter-api", Versions.Libraries.Internal.junit)
|
||||
testImplementation("org.junit.jupiter", "junit-jupiter-engine", Versions.Libraries.Internal.junit)
|
||||
compileOnly("org.jetbrains", "annotations", Versions.Libraries.Internal.jetBrainsAnnotations)
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.7.0")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.7.0")
|
||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||
|
||||
compileOnly("com.google.guava", "guava", Versions.Libraries.Internal.guava)
|
||||
testImplementation("com.google.guava", "guava", Versions.Libraries.Internal.guava)
|
||||
compileOnly("com.google.guava:guava:30.0-jre")
|
||||
testImplementation("com.google.guava:guava:30.0-jre")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@ import kotlin.io.path.exists
|
||||
|
||||
|
||||
fun Project.configureDistribution() {
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
|
||||
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
||||
group = "terra"
|
||||
doFirst {
|
||||
file("${buildDir}/resources/main/packs/").deleteRecursively()
|
||||
val defaultPackUrl =
|
||||
URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/" + Versions.Terra.overworldConfig + "/default.zip")
|
||||
val defaultPackUrl = URL("https://github.com/PolyhedralDev/TerraOverworldConfig/releases/download/latest/default.zip")
|
||||
downloadPack(defaultPackUrl, project)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,26 @@
|
||||
object Versions {
|
||||
object Terra {
|
||||
const val overworldConfig = "v1.3.4"
|
||||
}
|
||||
|
||||
object Libraries {
|
||||
const val tectonic = "4.2.1"
|
||||
const val paralithic = "0.7.1"
|
||||
const val strata = "1.3.2"
|
||||
|
||||
const val cloud = "2.0.0"
|
||||
const val cloudPaper = "2.0.0-beta.10"
|
||||
const val cloudFabric = "2.0.0-beta.9"
|
||||
const val cloud = "1.8.4"
|
||||
|
||||
const val caffeine = "3.1.8"
|
||||
const val slf4j = "2.0.9"
|
||||
const val log4j_slf4j_impl = "2.20.0"
|
||||
|
||||
const val slf4j = "2.0.16"
|
||||
|
||||
object Internal {
|
||||
const val shadow = "8.3.1"
|
||||
const val apacheText = "1.12.0"
|
||||
const val apacheIO = "2.16.1"
|
||||
const val guava = "33.3.0-jre"
|
||||
const val asm = "9.7"
|
||||
const val snakeYml = "2.3"
|
||||
const val jetBrainsAnnotations = "24.1.0"
|
||||
const val junit = "5.11.0"
|
||||
const val shadow = "8.1.1"
|
||||
const val apacheText = "1.10.0"
|
||||
const val apacheIO = "2.14.0"
|
||||
const val guava = "32.1.3-jre"
|
||||
const val asm = "9.5"
|
||||
const val snakeYml = "2.2"
|
||||
}
|
||||
}
|
||||
|
||||
object Fabric {
|
||||
const val fabricAPI = "0.104.0+${Mod.minecraft}"
|
||||
const val fabricAPI = "0.90.0+${Mod.minecraft}"
|
||||
}
|
||||
//
|
||||
// object Quilt {
|
||||
@@ -38,30 +29,32 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Mod {
|
||||
const val mixin = "0.15.3+mixin.0.8.7"
|
||||
const val mixin = "0.12.5+mixin.0.8.5"
|
||||
|
||||
const val minecraft = "1.21.1"
|
||||
const val yarn = "$minecraft+build.3"
|
||||
const val fabricLoader = "0.16.5"
|
||||
const val minecraft = "1.20.2"
|
||||
const val yarn = "$minecraft+build.4"
|
||||
const val fabricLoader = "0.14.23"
|
||||
|
||||
const val architecuryLoom = "1.7.413"
|
||||
const val architecturyPlugin = "3.4.159"
|
||||
const val architecuryLoom = "1.3.357"
|
||||
const val architecturyPlugin = "3.4.146"
|
||||
|
||||
const val loomVineflower = "1.11.0"
|
||||
}
|
||||
|
||||
object Forge {
|
||||
const val forge = "${Mod.minecraft}-48.0.13"
|
||||
const val burningwave = "12.63.0"
|
||||
}
|
||||
//
|
||||
// object Forge {
|
||||
// const val forge = "${Mod.minecraft}-48.0.13"
|
||||
// const val burningwave = "12.63.0"
|
||||
// }
|
||||
|
||||
object Bukkit {
|
||||
const val minecraft = "1.21.1"
|
||||
const val paperBuild = "$minecraft-R0.1-20240917.151311-80"
|
||||
const val paper = paperBuild
|
||||
const val paperLib = "1.0.8"
|
||||
const val reflectionRemapper = "0.1.1"
|
||||
const val paperDevBundle = paperBuild
|
||||
const val runPaper = "2.3.1"
|
||||
const val paperWeight = "1.7.2"
|
||||
const val paper = "1.18.2-R0.1-SNAPSHOT"
|
||||
const val paperLib = "1.0.5"
|
||||
const val foliaLib = "0.2.5"
|
||||
const val minecraft = "1.20.2"
|
||||
const val reflectionRemapper = "0.1.0-SNAPSHOT"
|
||||
const val paperDevBundle = "1.20.2-R0.1-SNAPSHOT"
|
||||
const val runPaper = "2.2.0"
|
||||
const val paperWeight = "1.5.6"
|
||||
}
|
||||
|
||||
//
|
||||
@@ -73,7 +66,6 @@ object Versions {
|
||||
//
|
||||
object CLI {
|
||||
const val nbt = "6.1"
|
||||
const val logback = "1.5.8"
|
||||
const val picocli = "4.7.6"
|
||||
const val logback = "1.4.11"
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
public interface Extrusion {
|
||||
Biome extrude(Biome original, int x, int y, int z, long seed);
|
||||
|
||||
+4
-4
@@ -1,9 +1,5 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||
import com.dfsek.terra.addons.biome.query.api.BiomeQueries;
|
||||
@@ -12,6 +8,10 @@ import com.dfsek.terra.api.util.Range;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* Sets biomes at locations based on a sampler.
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class BiomePipelineTemplate implements ObjectTemplate<BiomeProvider> {
|
||||
@Default
|
||||
@Description("""
|
||||
The resolution at which to sample biomes.
|
||||
|
||||
|
||||
Larger values are quadratically faster, but produce lower quality results.
|
||||
For example, a value of 3 would sample every 3 blocks.""")
|
||||
protected @Meta int resolution = 1;
|
||||
|
||||
+12
-16
@@ -14,8 +14,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
private final SeededVector worldOrigin;
|
||||
private final int chunkOriginArrayIndex;
|
||||
private final int worldCoordinateScale;
|
||||
private final int size;
|
||||
private PipelineBiome[] biomes;
|
||||
private PipelineBiome[][] biomes;
|
||||
|
||||
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
|
||||
|
||||
@@ -23,14 +22,14 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex();
|
||||
this.worldCoordinateScale = pipeline.getResolution();
|
||||
|
||||
this.size = pipeline.getArraySize();
|
||||
int size = pipeline.getArraySize();
|
||||
|
||||
int expanderCount = pipeline.getExpanderCount();
|
||||
int expansionsApplied = 0;
|
||||
|
||||
// Allocate working arrays
|
||||
this.biomes = new PipelineBiome[size * size];
|
||||
PipelineBiome[] lookupArray = new PipelineBiome[size * size];
|
||||
this.biomes = new PipelineBiome[size][size];
|
||||
PipelineBiome[][] lookupArray = new PipelineBiome[size][size];
|
||||
// A second lookup array is required such that stage application doesn't affect lookups, otherwise application may cascade
|
||||
|
||||
// Construct working grid
|
||||
@@ -44,7 +43,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
for(int gridZ = 0; gridZ < gridSize; gridZ++) {
|
||||
int xIndex = gridOrigin + gridX * gridInterval;
|
||||
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||
biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
|
||||
biomes[xIndex][zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
|
||||
zIndexToWorldCoordinate(zIndex));
|
||||
}
|
||||
}
|
||||
@@ -66,7 +65,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
|
||||
// Cycle arrays, the previously populated array is swapped to be used for lookups, and the result of the stage application
|
||||
// overwrites the previous lookup array. This saves having to allocate a new array copy each time
|
||||
PipelineBiome[] tempArray = biomes;
|
||||
PipelineBiome[][] tempArray = biomes;
|
||||
biomes = lookupArray;
|
||||
lookupArray = tempArray;
|
||||
|
||||
@@ -75,8 +74,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
for(int gridX = 0; gridX < gridSize; gridX = gridX + 1) {
|
||||
int xIndex = gridOrigin + gridX * gridInterval;
|
||||
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||
biomes[(xIndex * size) + zIndex] = stage.apply(
|
||||
new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray, size));
|
||||
biomes[xIndex][zIndex] = stage.apply(new ViewPoint(this, gridInterval, gridX, gridZ, xIndex, zIndex, lookupArray));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +133,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
public PipelineBiome get(int xInChunk, int zInChunk) {
|
||||
int xIndex = xInChunk + chunkOriginArrayIndex;
|
||||
int zIndex = zInChunk + chunkOriginArrayIndex;
|
||||
return biomes[(xIndex * size) + zIndex];
|
||||
return biomes[xIndex][zIndex];
|
||||
}
|
||||
|
||||
private int xIndexToWorldCoordinate(int xIndex) {
|
||||
@@ -161,11 +159,10 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
private final int gridZ;
|
||||
private final int xIndex;
|
||||
private final int zIndex;
|
||||
private final PipelineBiome[] lookupArray;
|
||||
private final int size;
|
||||
private final PipelineBiome[][] lookupArray;
|
||||
|
||||
private ViewPoint(BiomeChunkImpl chunk, int gridInterval, int gridX, int gridZ, int xIndex, int zIndex,
|
||||
PipelineBiome[] lookupArray, int size) {
|
||||
PipelineBiome[][] lookupArray) {
|
||||
this.chunk = chunk;
|
||||
this.gridInterval = gridInterval;
|
||||
this.gridX = gridX;
|
||||
@@ -173,14 +170,13 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
this.xIndex = xIndex;
|
||||
this.zIndex = zIndex;
|
||||
this.lookupArray = lookupArray;
|
||||
this.size = size;
|
||||
this.biome = lookupArray[(this.xIndex * this.size) + this.zIndex];
|
||||
this.biome = lookupArray[xIndex][zIndex];
|
||||
}
|
||||
|
||||
public PipelineBiome getRelativeBiome(int x, int z) {
|
||||
int lookupXIndex = this.xIndex + x * gridInterval;
|
||||
int lookupZIndex = this.zIndex + z * gridInterval;
|
||||
return lookupArray[(lookupXIndex * this.size) + lookupZIndex];
|
||||
return lookupArray[lookupXIndex][lookupZIndex];
|
||||
}
|
||||
|
||||
public PipelineBiome getBiome() {
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class BiomePipelineTemplate extends BiomeProviderTemplate {
|
||||
@Description("""
|
||||
The initial size of biome chunks. This value must be at least 2.
|
||||
<b>This is not the final size of biome chunks. Final chunks will be much larger</b>.
|
||||
|
||||
|
||||
It is recommended to keep biome chunks' final size in the range of [50, 300]
|
||||
to prevent performance issues. To calculate the size of biome chunks, simply
|
||||
take initial-size and for each expand stage, multiply the running value by 2
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ public abstract class BiomeProviderTemplate implements ObjectTemplate<BiomeProvi
|
||||
@Default
|
||||
@Description("""
|
||||
The resolution at which to sample biomes.
|
||||
|
||||
|
||||
Larger values are quadratically faster, but produce lower quality results.
|
||||
For example, a value of 3 would sample every 3 blocks.""")
|
||||
protected @Meta int resolution = 1;
|
||||
|
||||
+3
-5
@@ -13,7 +13,6 @@ import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.BiomePaletteTemplate;
|
||||
import com.dfsek.terra.addons.chunkgenerator.config.palette.slant.SlantLayerTemplate;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.NoiseChunkGenerator3D;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
@@ -46,8 +45,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
|
||||
.priority(1000)
|
||||
.then(event -> {
|
||||
|
||||
event.getPack().applyLoader(SlantCalculationMethod.class,
|
||||
(type, o, loader, depthTracker) -> SlantCalculationMethod.valueOf((String) o));
|
||||
event.getPack().applyLoader(SlantHolder.CalculationMethod.class,
|
||||
(type, o, loader, depthTracker) -> SlantHolder.CalculationMethod.valueOf((String) o));
|
||||
|
||||
NoiseChunkGeneratorPackConfigTemplate config = event.loadTemplate(new NoiseChunkGeneratorPackConfigTemplate());
|
||||
event.getPack().getContext().put(config);
|
||||
@@ -58,8 +57,7 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
|
||||
pack -> new NoiseChunkGenerator3D(pack, platform, config.getElevationBlend(),
|
||||
config.getHorizontalRes(),
|
||||
config.getVerticalRes(), noisePropertiesPropertyKey,
|
||||
paletteInfoPropertyKey, config.getSlantCalculationMethod(),
|
||||
config.isSlantPalettesEnabled()));
|
||||
paletteInfoPropertyKey));
|
||||
event.getPack()
|
||||
.applyLoader(SlantHolder.Layer.class, SlantLayerTemplate::new);
|
||||
})
|
||||
|
||||
+3
-11
@@ -4,7 +4,7 @@ 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 com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
@@ -24,11 +24,7 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Pr
|
||||
|
||||
@Value("slant.calculation-method")
|
||||
@Default
|
||||
private @Meta SlantCalculationMethod slantCalculationMethod = SlantCalculationMethod.Derivative;
|
||||
|
||||
@Value("slant.disable-palettes")
|
||||
@Default
|
||||
private @Meta boolean disableSlantPalettes = false;
|
||||
private SlantHolder.@Meta CalculationMethod slantCalculationMethod = SlantHolder.CalculationMethod.Derivative;
|
||||
|
||||
public int getElevationBlend() {
|
||||
return elevationBlend;
|
||||
@@ -42,11 +38,7 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Pr
|
||||
return verticalRes;
|
||||
}
|
||||
|
||||
public SlantCalculationMethod getSlantCalculationMethod() {
|
||||
public SlantHolder.CalculationMethod getSlantCalculationMethod() {
|
||||
return slantCalculationMethod;
|
||||
}
|
||||
|
||||
public boolean isSlantPalettesEnabled() {
|
||||
return !disableSlantPalettes;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -16,7 +16,6 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
@@ -28,7 +27,7 @@ import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||
|
||||
public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
|
||||
private final Platform platform;
|
||||
private final SlantCalculationMethod slantCalculationMethod;
|
||||
private final SlantHolder.CalculationMethod slantCalculationMethod;
|
||||
@Value("slant")
|
||||
@Default
|
||||
@Description("The slant palettes to use in this biome.")
|
||||
@@ -57,7 +56,7 @@ public class BiomePaletteTemplate implements ObjectTemplate<BiomePaletteInfo> {
|
||||
@Default
|
||||
private @Meta boolean updatePalette = false;
|
||||
|
||||
public BiomePaletteTemplate(Platform platform, SlantCalculationMethod slantCalculationMethod) {
|
||||
public BiomePaletteTemplate(Platform platform, SlantHolder.CalculationMethod slantCalculationMethod) {
|
||||
this.platform = platform;
|
||||
this.slantCalculationMethod = slantCalculationMethod;
|
||||
}
|
||||
|
||||
+10
-25
@@ -11,12 +11,11 @@ package com.dfsek.terra.addons.chunkgenerator.generation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.PaletteUtil;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.LazilyEvaluatedInterpolator;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.SamplerProvider;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
@@ -43,23 +42,16 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
private final PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey;
|
||||
private final PropertyKey<BiomeNoiseProperties> noisePropertiesKey;
|
||||
|
||||
private final SlantCalculationMethod slantCalculationMethod;
|
||||
|
||||
private final boolean useSlantPalettes;
|
||||
|
||||
public NoiseChunkGenerator3D(ConfigPack pack, Platform platform, int elevationBlend, int carverHorizontalResolution,
|
||||
int carverVerticalResolution,
|
||||
PropertyKey<BiomeNoiseProperties> noisePropertiesKey,
|
||||
PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey,
|
||||
SlantCalculationMethod slantCalculationMethod, boolean useSlantPalettes) {
|
||||
PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey) {
|
||||
this.platform = platform;
|
||||
this.air = platform.getWorldHandle().air();
|
||||
this.carverHorizontalResolution = carverHorizontalResolution;
|
||||
this.carverVerticalResolution = carverVerticalResolution;
|
||||
this.paletteInfoPropertyKey = paletteInfoPropertyKey;
|
||||
this.noisePropertiesKey = noisePropertiesKey;
|
||||
this.slantCalculationMethod = slantCalculationMethod;
|
||||
this.useSlantPalettes = useSlantPalettes;
|
||||
int maxBlend = pack
|
||||
.getBiomeProvider()
|
||||
.stream()
|
||||
@@ -71,17 +63,6 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
this.samplerCache = new SamplerProvider(platform, elevationBlend, noisePropertiesKey, maxBlend);
|
||||
}
|
||||
|
||||
private Palette paletteAt(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) {
|
||||
SlantHolder slantHolder = paletteInfo.slantHolder();
|
||||
if(useSlantPalettes && slantHolder.isAboveDepth(depth)) {
|
||||
double slant = slantCalculationMethod.slant(sampler, x, y, z);
|
||||
if(slantHolder.isInSlantThreshold(slant)) {
|
||||
return slantHolder.getPalette(slant).getPalette(y);
|
||||
}
|
||||
}
|
||||
return paletteInfo.paletteHolder().getPalette(y);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public void generateChunkData(@NotNull ProtoChunk chunk, @NotNull WorldProperties world,
|
||||
@@ -122,7 +103,8 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
|
||||
if(sampler.sample(x, y, z) > 0) {
|
||||
if(carver.sample(x, y, z) <= 0) {
|
||||
data = paletteAt(x, y, z, sampler, paletteInfo, paletteLevel)
|
||||
data = PaletteUtil
|
||||
.getPalette(x, y, z, sampler, paletteInfo, paletteLevel)
|
||||
.get(paletteLevel, cx, y, cz, seed);
|
||||
chunk.setBlock(x, y, z, data);
|
||||
paletteLevel++;
|
||||
@@ -153,7 +135,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
int fdX = Math.floorMod(x, 16);
|
||||
int fdZ = Math.floorMod(z, 16);
|
||||
|
||||
Palette palette = paletteAt(fdX, y, fdZ, sampler, paletteInfo, 0);
|
||||
Palette palette = PaletteUtil.getPalette(fdX, y, fdZ, sampler, paletteInfo, 0);
|
||||
double noise = sampler.sample(fdX, y, fdZ);
|
||||
if(noise > 0) {
|
||||
int level = 0;
|
||||
@@ -175,8 +157,11 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
public double getSlant(int x, int y, int z, WorldProperties world, BiomeProvider biomeProvider) {
|
||||
int fdX = Math.floorMod(x, 16);
|
||||
int fdZ = Math.floorMod(z, 16);
|
||||
Sampler3D sampler = samplerCache.get(x, z, world, biomeProvider);
|
||||
return slantCalculationMethod.slant(sampler, fdX, y, fdZ);
|
||||
return biomeProvider.getBiome(x, y, z, world.getSeed())
|
||||
.getContext()
|
||||
.get(paletteInfoPropertyKey)
|
||||
.slantHolder()
|
||||
.calculateSlant(samplerCache.get(x, z, world, biomeProvider), fdX, y, fdZ);
|
||||
}
|
||||
|
||||
public SamplerProvider samplerProvider() {
|
||||
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 Polyhedral Development
|
||||
*
|
||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in this module's root directory.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.addons.chunkgenerator.generation.math;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.BiomePaletteInfo;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||
|
||||
|
||||
public final class PaletteUtil {
|
||||
|
||||
public static Palette getPalette(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) {
|
||||
SlantHolder slantHolder = paletteInfo.slantHolder();
|
||||
if(slantHolder.isAboveDepth(depth)) {
|
||||
double slant = slantHolder.calculateSlant(sampler, x, y, z);
|
||||
if(slantHolder.isInSlantThreshold(slant)) {
|
||||
return slantHolder.getPalette(slant).getPalette(y);
|
||||
}
|
||||
}
|
||||
|
||||
return paletteInfo.paletteHolder().getPalette(y);
|
||||
}
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package com.dfsek.terra.addons.chunkgenerator.generation.math;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
|
||||
|
||||
public enum SlantCalculationMethod {
|
||||
DotProduct {
|
||||
private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0);
|
||||
|
||||
private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = {
|
||||
Vector3.of(0, 0, -DERIVATIVE_DIST),
|
||||
Vector3.of(0, 0, DERIVATIVE_DIST),
|
||||
Vector3.of(0, -DERIVATIVE_DIST, 0),
|
||||
Vector3.of(0, DERIVATIVE_DIST, 0),
|
||||
Vector3.of(-DERIVATIVE_DIST, 0, 0),
|
||||
Vector3.of(DERIVATIVE_DIST, 0, 0)
|
||||
};
|
||||
|
||||
@Override
|
||||
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
|
||||
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
|
||||
var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ());
|
||||
normalApproximation.add(point.mutable().multiply(scalar));
|
||||
}
|
||||
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean floorToThreshold() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
Derivative {
|
||||
@Override
|
||||
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||
double baseSample = sampler.sample(x, y, z);
|
||||
|
||||
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
||||
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
||||
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
|
||||
|
||||
return Math.sqrt(
|
||||
((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean floorToThreshold() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static final double DERIVATIVE_DIST = 0.55;
|
||||
|
||||
public abstract double slant(Sampler3D sampler, double x, double y, double z);
|
||||
|
||||
/*
|
||||
* Controls whether palettes should be applied before or after their respective thresholds.
|
||||
*
|
||||
* If true, slant values will map to the palette of the next floor threshold, otherwise they
|
||||
* will map to the ceiling.
|
||||
*/
|
||||
public abstract boolean floorToThreshold();
|
||||
}
|
||||
+1
-2
@@ -14,7 +14,6 @@ import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||
|
||||
|
||||
@@ -22,7 +21,7 @@ public class MultipleSlantHolder extends SlantHolderImpl {
|
||||
private final NavigableMap<Double, PaletteHolder> layers;
|
||||
private final double slantThreshold;
|
||||
|
||||
MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, SlantCalculationMethod calculationMethod) {
|
||||
MultipleSlantHolder(List<SlantHolder.Layer> slant, int slantDepth, CalculationMethod calculationMethod) {
|
||||
super(slantDepth, calculationMethod);
|
||||
NavigableMap<Double, PaletteHolder> layers = new TreeMap<>(
|
||||
slant.stream().collect(Collectors.toMap(SlantHolder.Layer::threshold, SlantHolder.Layer::palette)));
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||
|
||||
|
||||
@@ -8,7 +7,7 @@ final class SingleSlantHolder extends SlantHolderImpl {
|
||||
|
||||
private final SlantHolder.Layer layer;
|
||||
|
||||
public SingleSlantHolder(SlantHolder.Layer layer, int slantDepth, SlantCalculationMethod calculationMethod) {
|
||||
public SingleSlantHolder(SlantHolder.Layer layer, int slantDepth, CalculationMethod calculationMethod) {
|
||||
super(slantDepth, calculationMethod);
|
||||
this.layer = layer;
|
||||
}
|
||||
|
||||
+75
-2
@@ -2,13 +2,19 @@ package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.PaletteHolder;
|
||||
import com.dfsek.terra.api.util.vector.Vector3;
|
||||
|
||||
|
||||
public interface SlantHolder {
|
||||
|
||||
SlantHolder EMPTY = new SlantHolder() {
|
||||
@Override
|
||||
public double calculateSlant(Sampler3D sampler, double x, double y, double z) {
|
||||
throw new UnsupportedOperationException("Empty holder should not calculate slant");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAboveDepth(int depth) {
|
||||
return false;
|
||||
@@ -25,7 +31,7 @@ public interface SlantHolder {
|
||||
}
|
||||
};
|
||||
|
||||
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, SlantCalculationMethod calculationMethod) {
|
||||
static SlantHolder of(List<SlantHolder.Layer> layers, int slantDepth, CalculationMethod calculationMethod) {
|
||||
if(layers.isEmpty()) {
|
||||
return EMPTY;
|
||||
} else if(layers.size() == 1) {
|
||||
@@ -34,6 +40,8 @@ public interface SlantHolder {
|
||||
return new MultipleSlantHolder(layers, slantDepth, calculationMethod);
|
||||
}
|
||||
|
||||
double calculateSlant(Sampler3D sampler, double x, double y, double z);
|
||||
|
||||
boolean isAboveDepth(int depth);
|
||||
|
||||
boolean isInSlantThreshold(double slant);
|
||||
@@ -41,6 +49,71 @@ public interface SlantHolder {
|
||||
PaletteHolder getPalette(double slant);
|
||||
|
||||
|
||||
enum CalculationMethod {
|
||||
DotProduct {
|
||||
private static final Vector3 DOT_PRODUCT_DIRECTION = Vector3.of(0, 1, 0);
|
||||
|
||||
private static final Vector3[] DOT_PRODUCT_SAMPLE_POINTS = {
|
||||
Vector3.of(0, 0, -DERIVATIVE_DIST),
|
||||
Vector3.of(0, 0, DERIVATIVE_DIST),
|
||||
Vector3.of(0, -DERIVATIVE_DIST, 0),
|
||||
Vector3.of(0, DERIVATIVE_DIST, 0),
|
||||
Vector3.of(-DERIVATIVE_DIST, 0, 0),
|
||||
Vector3.of(DERIVATIVE_DIST, 0, 0)
|
||||
};
|
||||
|
||||
@Override
|
||||
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||
Vector3.Mutable normalApproximation = Vector3.Mutable.of(0, 0, 0);
|
||||
for(Vector3 point : DOT_PRODUCT_SAMPLE_POINTS) {
|
||||
var scalar = -sampler.sample(x + point.getX(), y + point.getY(), z + point.getZ());
|
||||
normalApproximation.add(point.mutable().multiply(scalar));
|
||||
}
|
||||
return DOT_PRODUCT_DIRECTION.dot(normalApproximation.normalize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean floorToThreshold() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
Derivative {
|
||||
@Override
|
||||
public double slant(Sampler3D sampler, double x, double y, double z) {
|
||||
double baseSample = sampler.sample(x, y, z);
|
||||
|
||||
double xVal1 = (sampler.sample(x + DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double xVal2 = (sampler.sample(x - DERIVATIVE_DIST, y, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double zVal1 = (sampler.sample(x, y, z + DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
||||
double zVal2 = (sampler.sample(x, y, z - DERIVATIVE_DIST) - baseSample) / DERIVATIVE_DIST;
|
||||
double yVal1 = (sampler.sample(x, y + DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
|
||||
double yVal2 = (sampler.sample(x, y - DERIVATIVE_DIST, z) - baseSample) / DERIVATIVE_DIST;
|
||||
|
||||
return Math.sqrt(
|
||||
((xVal2 - xVal1) * (xVal2 - xVal1)) + ((zVal2 - zVal1) * (zVal2 - zVal1)) + ((yVal2 - yVal1) * (yVal2 - yVal1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean floorToThreshold() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static final double DERIVATIVE_DIST = 0.55;
|
||||
|
||||
public abstract double slant(Sampler3D sampler, double x, double y, double z);
|
||||
|
||||
/*
|
||||
* Controls whether palettes should be applied before or after their respective thresholds.
|
||||
*
|
||||
* If true, slant values will map to the palette of the next floor threshold, otherwise they
|
||||
* will map to the ceiling.
|
||||
*/
|
||||
public abstract boolean floorToThreshold();
|
||||
}
|
||||
|
||||
|
||||
record Layer(PaletteHolder palette, double threshold) {
|
||||
}
|
||||
}
|
||||
|
||||
+9
-2
@@ -1,19 +1,26 @@
|
||||
package com.dfsek.terra.addons.chunkgenerator.palette.slant;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.samplers.Sampler3D;
|
||||
|
||||
|
||||
public abstract class SlantHolderImpl implements SlantHolder {
|
||||
protected final boolean floorToThreshold;
|
||||
private final SlantHolder.CalculationMethod calculationMethod;
|
||||
private final int slantDepth;
|
||||
|
||||
protected SlantHolderImpl(int slantDepth, SlantCalculationMethod calculationMethod) {
|
||||
protected SlantHolderImpl(int slantDepth, CalculationMethod calculationMethod) {
|
||||
this.floorToThreshold = calculationMethod.floorToThreshold();
|
||||
this.calculationMethod = calculationMethod;
|
||||
this.slantDepth = slantDepth;
|
||||
}
|
||||
|
||||
protected abstract double getSlantThreshold();
|
||||
|
||||
@Override
|
||||
public final double calculateSlant(Sampler3D sampler, double x, double y, double z) {
|
||||
return calculationMethod.slant(sampler, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final boolean isAboveDepth(int depth) {
|
||||
return depth <= slantDepth;
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.addons;
|
||||
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
@@ -30,7 +30,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("addons", Description.of("List installed Terra addons"))
|
||||
manager.commandBuilder("addons", ArgumentDescription.of("List installed Terra addons"))
|
||||
.permission("terra.addons")
|
||||
.handler(context -> {
|
||||
StringBuilder addons = new StringBuilder("Installed addons:\n");
|
||||
@@ -41,7 +41,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(addon.getVersion().getFormatted())
|
||||
.append('\n'));
|
||||
context.sender().sendMessage(addons.toString());
|
||||
context.getSender().sendMessage(addons.toString());
|
||||
})
|
||||
)
|
||||
.command(
|
||||
@@ -61,7 +61,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(versions.getFormatted())
|
||||
.append('\n'));
|
||||
context.sender().sendMessage(addonInfo.toString());
|
||||
context.getSender().sendMessage(addonInfo.toString());
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.packs;
|
||||
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("packs", Description.of("List installed config packs"))
|
||||
manager.commandBuilder("packs", ArgumentDescription.of("List installed config packs"))
|
||||
.permission("terra.packs")
|
||||
.handler(context -> {
|
||||
StringBuilder packs = new StringBuilder("Installed packs:\n");
|
||||
@@ -43,12 +43,12 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
.append(pack.getID())
|
||||
.append('@')
|
||||
.append(pack.getVersion().getFormatted()));
|
||||
context.sender().sendMessage(packs.toString());
|
||||
context.getSender().sendMessage(packs.toString());
|
||||
})
|
||||
)
|
||||
.command(
|
||||
manager.commandBuilder("packs")
|
||||
.literal("info", Description.of("Get information about a pack"))
|
||||
.literal("info", ArgumentDescription.of("Get information about a pack"))
|
||||
.permission("terra.packs.info")
|
||||
.argument(RegistryArgument.of("pack", platform.getConfigRegistry()))
|
||||
.handler(context -> {
|
||||
@@ -65,21 +65,21 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(versions.getFormatted())
|
||||
.append('\n'));
|
||||
context.sender().sendMessage(packInfo.toString());
|
||||
context.getSender().sendMessage(packInfo.toString());
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("packs")
|
||||
.literal("reload", Description.of("Reload config packs"))
|
||||
.literal("reload", ArgumentDescription.of("Reload config packs"))
|
||||
.permission("terra.packs.reload")
|
||||
.handler(context -> {
|
||||
context.sender().sendMessage("Reloading Terra...");
|
||||
context.getSender().sendMessage("Reloading Terra...");
|
||||
logger.info("Reloading Terra...");
|
||||
if(platform.reload()) {
|
||||
logger.info("Terra reloaded successfully.");
|
||||
context.sender().sendMessage("Terra reloaded successfully.");
|
||||
context.getSender().sendMessage("Terra reloaded successfully.");
|
||||
} else {
|
||||
logger.error("Terra failed to reload.");
|
||||
context.sender().sendMessage(
|
||||
context.getSender().sendMessage(
|
||||
"Terra failed to reload. See logs for more information.");
|
||||
}
|
||||
}));
|
||||
|
||||
+14
-14
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.profiler;
|
||||
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -33,24 +33,24 @@ public class ProfilerCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
manager
|
||||
.command(
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("start", Description.of("Start profiling"), "st")
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("start", ArgumentDescription.of("Start profiling"), "st")
|
||||
.permission("terra.profiler.start")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().start();
|
||||
context.sender().sendMessage("Profiling started.");
|
||||
context.getSender().sendMessage("Profiling started.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("stop", Description.of("Stop profiling"), "s")
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("stop", ArgumentDescription.of("Stop profiling"), "s")
|
||||
.permission("terra.profiler.stop")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().stop();
|
||||
context.sender().sendMessage("Profiling stopped.");
|
||||
context.getSender().sendMessage("Profiling stopped.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("query", Description.of("Query profiler results"), "q")
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("query", ArgumentDescription.of("Query profiler results"), "q")
|
||||
.permission("terra.profiler.query")
|
||||
.handler(context -> {
|
||||
StringBuilder data = new StringBuilder("Terra Profiler data: \n");
|
||||
@@ -59,15 +59,15 @@ public class ProfilerCommandAddon implements AddonInitializer {
|
||||
.append(timings.toString())
|
||||
.append('\n'));
|
||||
logger.info(data.toString());
|
||||
context.sender().sendMessage("Profiling data dumped to console.");
|
||||
context.getSender().sendMessage("Profiling data dumped to console.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("reset", Description.of("Reset the profiler"), "r")
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("reset", ArgumentDescription.of("Reset the profiler"), "r")
|
||||
.permission("terra.profiler.reset")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().reset();
|
||||
context.sender().sendMessage("Profiler reset.");
|
||||
context.getSender().sendMessage("Profiler reset.");
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
+11
-12
@@ -1,11 +1,10 @@
|
||||
package com.dfsek.terra.addons.commands.structure;
|
||||
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.component.DefaultValue;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.incendo.cloud.parser.standard.LongParser;
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.arguments.standard.EnumArgument;
|
||||
import cloud.commandframework.arguments.standard.LongArgument;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@@ -32,7 +31,7 @@ public class StructureCommandAddon implements AddonInitializer {
|
||||
private BaseAddon addon;
|
||||
|
||||
private static Registry<Structure> getStructureRegistry(CommandContext<CommandSender> sender) {
|
||||
return sender.sender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class);
|
||||
return sender.getSender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,16 +43,16 @@ public class StructureCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("structures", Description.of("Manage or generate structures"))
|
||||
manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures"))
|
||||
.literal("generate")
|
||||
.optional(RegistryArgument.builder("structure",
|
||||
.argument(RegistryArgument.builder("structure",
|
||||
StructureCommandAddon::getStructureRegistry,
|
||||
TypeKey.of(Structure.class)))
|
||||
.optional("seed", LongParser.longParser(), DefaultValue.constant(0L))
|
||||
.optional("rotation", EnumParser.enumParser(Rotation.class), DefaultValue.constant(Rotation.NONE))
|
||||
.argument(LongArgument.optional("seed", 0))
|
||||
.argument(EnumArgument.optional(Rotation.class, "rotation", Rotation.NONE))
|
||||
.handler(context -> {
|
||||
Structure structure = context.get("structure");
|
||||
Entity sender = context.sender().getEntity().orElseThrow();
|
||||
Entity sender = context.getSender().getEntity().orElseThrow();
|
||||
structure.generate(
|
||||
sender.position().toInt(),
|
||||
sender.world(),
|
||||
|
||||
+2
-2
@@ -7,11 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.biome.holder;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.Palette;
|
||||
|
||||
|
||||
public class PaletteHolderBuilder {
|
||||
private final TreeMap<Integer, Palette> paletteMap = new TreeMap<>();
|
||||
|
||||
+2
-2
@@ -7,11 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.feature.distributor.distributors;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.addons.feature.distributor.util.Point;
|
||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class PointSetDistributor implements Distributor {
|
||||
private final Set<Point> points;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version = version("1.2.0")
|
||||
version = version("1.1.0")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
|
||||
+2
-11
@@ -17,8 +17,6 @@ import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.CacheSamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.ImageSamplerTemplate;
|
||||
@@ -30,7 +28,6 @@ import com.dfsek.terra.addons.noise.config.templates.noise.ConstantNoiseTemplate
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.DistanceSamplerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.ExpressionFunctionTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.GaborNoiseTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.PseudoErosionTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.SimpleNoiseTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.BrownianMotionTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate;
|
||||
@@ -38,7 +35,6 @@ import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractal
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.CubicSplineNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.ExpressionNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearMapNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
|
||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
|
||||
@@ -67,7 +63,6 @@ import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
@@ -99,11 +94,9 @@ public class NoiseAddon implements AddonInitializer {
|
||||
(type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o))
|
||||
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
|
||||
.applyLoader(FunctionTemplate.class, FunctionTemplate::new)
|
||||
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new)
|
||||
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
|
||||
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new);
|
||||
|
||||
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
|
||||
noiseRegistry.register(addon.key("LINEAR_MAP"), LinearMapNormalizerTemplate::new);
|
||||
noiseRegistry.register(addon.key("NORMAL"), NormalNormalizerTemplate::new);
|
||||
noiseRegistry.register(addon.key("CLAMP"), ClampNormalizerTemplate::new);
|
||||
noiseRegistry.register(addon.key("PROBABILITY"), ProbabilityNormalizerTemplate::new);
|
||||
@@ -124,7 +117,7 @@ public class NoiseAddon implements AddonInitializer {
|
||||
noiseRegistry.register(addon.key("PERLIN"), () -> new SimpleNoiseTemplate(PerlinSampler::new));
|
||||
noiseRegistry.register(addon.key("SIMPLEX"), () -> new SimpleNoiseTemplate(SimplexSampler::new));
|
||||
noiseRegistry.register(addon.key("GABOR"), GaborNoiseTemplate::new);
|
||||
noiseRegistry.register(addon.key("PSEUDOEROSION"), PseudoErosionTemplate::new);
|
||||
|
||||
|
||||
noiseRegistry.register(addon.key("VALUE"), () -> new SimpleNoiseTemplate(ValueSampler::new));
|
||||
noiseRegistry.register(addon.key("VALUE_CUBIC"), () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
|
||||
@@ -151,8 +144,6 @@ public class NoiseAddon implements AddonInitializer {
|
||||
noiseRegistry.register(addon.key("MAX"), () -> new BinaryArithmeticTemplate<>(MaxSampler::new));
|
||||
noiseRegistry.register(addon.key("MIN"), () -> new BinaryArithmeticTemplate<>(MinSampler::new));
|
||||
|
||||
noiseRegistry.register(addon.key("CACHE"), () -> new CacheSamplerTemplate(plugin.getGenerationThreads()));
|
||||
|
||||
|
||||
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
||||
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
||||
|
||||
+3
-3
@@ -11,14 +11,14 @@ 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.noise.config.DimensionApplicableNoiseSampler;
|
||||
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class NoiseConfigPackTemplate implements ConfigTemplate, Properties {
|
||||
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.CacheSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class CacheSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
|
||||
@Value("sampler")
|
||||
@Default
|
||||
private NoiseSampler sampler;
|
||||
|
||||
private final int generationThreads;
|
||||
|
||||
public CacheSamplerTemplate(int generationThreads) {
|
||||
this.generationThreads = generationThreads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
return new CacheSampler(sampler, getDimensions(), generationThreads);
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.exception.ValidationException;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class DerivativeNoiseSamplerTemplate extends SamplerTemplate<DerivativeNoiseSampler> {
|
||||
|
||||
@Value(".")
|
||||
private NoiseSampler sampler;
|
||||
|
||||
@Override
|
||||
public boolean validate() throws ValidationException {
|
||||
if(!DerivativeNoiseSampler.isDifferentiable(sampler)) throw new ValidationException(
|
||||
"Provided sampler does not support calculating a derivative");
|
||||
return super.validate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DerivativeNoiseSampler get() {
|
||||
return (DerivativeNoiseSampler) sampler;
|
||||
}
|
||||
}
|
||||
+1
-6
@@ -34,11 +34,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
@Value("lookup")
|
||||
@Default
|
||||
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
|
||||
|
||||
@Value("salt-lookup")
|
||||
@Default
|
||||
private @Meta boolean saltLookup = true;
|
||||
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
CellularSampler sampler = new CellularSampler();
|
||||
@@ -48,7 +44,6 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
sampler.setReturnType(cellularReturnType);
|
||||
sampler.setDistanceFunction(cellularDistanceFunction);
|
||||
sampler.setSalt(salt);
|
||||
sampler.setSaltLookup(saltLookup);
|
||||
return sampler;
|
||||
}
|
||||
}
|
||||
|
||||
-8
@@ -1,8 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
|
||||
|
||||
public abstract class DerivativeNoiseTemplate<T extends DerivativeNoiseFunction> extends NoiseTemplate<T> {
|
||||
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.PseudoErosionSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
|
||||
|
||||
public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
|
||||
@Value("frequency")
|
||||
@Default
|
||||
protected @Meta double frequency = 1d;
|
||||
|
||||
@Value("octaves")
|
||||
@Default
|
||||
private int octaves = 4;
|
||||
|
||||
@Value("lacunarity")
|
||||
@Default
|
||||
private double lacunarity = 2.0;
|
||||
|
||||
@Value("gain")
|
||||
@Default
|
||||
private double gain = 0.5;
|
||||
|
||||
@Value("slope-strength")
|
||||
@Default
|
||||
private double slopeStrength = 1.0;
|
||||
|
||||
|
||||
@Value("branch-strength")
|
||||
@Default
|
||||
private double branchStrength = 1.0;
|
||||
|
||||
@Value("strength")
|
||||
@Default
|
||||
private double strength = 0.04;
|
||||
|
||||
@Value("erosion-frequency")
|
||||
@Default
|
||||
private double erosionFrequency = 0.02;
|
||||
|
||||
@Value("sampler")
|
||||
@Default
|
||||
private DerivativeNoiseSampler heightSampler = new OpenSimplex2Sampler();
|
||||
|
||||
@Value("slope-mask.enable")
|
||||
@Default
|
||||
private boolean slopeMask = true;
|
||||
|
||||
@Value("slope-mask.none")
|
||||
@Default
|
||||
private double slopeMaskNone = -0.5;
|
||||
|
||||
@Value("slope-mask.full")
|
||||
@Default
|
||||
private double slopeMaskFull = 1;
|
||||
|
||||
@Value("jitter")
|
||||
@Default
|
||||
private double jitterModifier = 1;
|
||||
|
||||
@Value("average-impulses")
|
||||
@Default
|
||||
private boolean averageErosionImpulses = true;
|
||||
|
||||
@Override
|
||||
public PseudoErosionSampler get() {
|
||||
PseudoErosionSampler pseudoErosion = new PseudoErosionSampler(octaves, gain, lacunarity,
|
||||
slopeStrength, branchStrength, strength,
|
||||
erosionFrequency, heightSampler, slopeMask, slopeMaskFull, slopeMaskNone, jitterModifier, averageErosionImpulses);
|
||||
pseudoErosion.setFrequency(frequency);
|
||||
pseudoErosion.setSalt(salt);
|
||||
return pseudoErosion;
|
||||
}
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.noise.normalizer.LinearMapNormalizer;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class LinearMapNormalizerTemplate extends NormalizerTemplate<LinearMapNormalizer> {
|
||||
|
||||
@Value("from.a")
|
||||
@Default
|
||||
private @Meta double aFrom = -1;
|
||||
|
||||
@Value("from.b")
|
||||
@Default
|
||||
private @Meta double bFrom = 1;
|
||||
|
||||
@Value("to.a")
|
||||
private @Meta double aTo;
|
||||
|
||||
@Value("to.b")
|
||||
private @Meta double bTo;
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
return new LinearMapNormalizer(function, aFrom, aTo, bFrom, bTo);
|
||||
}
|
||||
}
|
||||
-28
@@ -1,28 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.normalizer;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class LinearMapNormalizer extends Normalizer {
|
||||
|
||||
private final double aFrom;
|
||||
|
||||
private final double aTo;
|
||||
|
||||
private final double bFrom;
|
||||
|
||||
private final double bTo;
|
||||
|
||||
public LinearMapNormalizer(NoiseSampler sampler, double aFrom, double aTo, double bFrom, double bTo) {
|
||||
super(sampler);
|
||||
this.aFrom = aFrom;
|
||||
this.aTo = aTo;
|
||||
this.bFrom = bFrom;
|
||||
this.bTo = bTo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double normalize(double in) {
|
||||
return (in - aFrom) * (aTo - bTo) / (aFrom - bFrom) + aTo;
|
||||
}
|
||||
}
|
||||
+4
-11
@@ -11,8 +11,6 @@ import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction2;
|
||||
import com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction3;
|
||||
|
||||
|
||||
public class FunctionUtil {
|
||||
@@ -25,15 +23,10 @@ public class FunctionUtil {
|
||||
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
|
||||
functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
|
||||
}
|
||||
samplers.forEach((id, sampler) -> {
|
||||
if(sampler.getDimensions() == 2) {
|
||||
functionMap.put(id, new NoiseFunction2(sampler.getSampler()));
|
||||
functionMap.put(id + "Salted", new SaltedNoiseFunction2(sampler.getSampler()));
|
||||
} else {
|
||||
functionMap.put(id, new NoiseFunction3(sampler.getSampler()));
|
||||
functionMap.put(id + "Salted", new SaltedNoiseFunction3(sampler.getSampler()));
|
||||
}
|
||||
});
|
||||
samplers.forEach((id, sampler) -> functionMap.put(id,
|
||||
sampler.getDimensions() == 2 ?
|
||||
new NoiseFunction2(sampler.getSampler()) :
|
||||
new NoiseFunction3(sampler.getSampler())));
|
||||
return functionMap;
|
||||
}
|
||||
}
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class SaltedNoiseFunction2 implements DynamicFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public SaltedNoiseFunction2(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(Context context, double... args) {
|
||||
return gen.noise(((SeedContext) context).getSeed() + (long) args[2], args[0], args[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class SaltedNoiseFunction3 implements DynamicFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public SaltedNoiseFunction3(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(Context context, double... args) {
|
||||
return gen.noise(((SeedContext) context).getSeed() + (long) args[3], args[0], args[1], args[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.samplers;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
|
||||
public class CacheSampler implements DerivativeNoiseSampler {
|
||||
|
||||
private final NoiseSampler sampler;
|
||||
private final LoadingCache<DoubleSeededVector2, Double> cache2D;
|
||||
private final LoadingCache<DoubleSeededVector3, Double> cache3D;
|
||||
private final LoadingCache<DoubleSeededVector2, double[]> cache2DDirv;
|
||||
private final LoadingCache<DoubleSeededVector3, double[]> cache3DDirv;
|
||||
|
||||
public CacheSampler(NoiseSampler sampler, int dimensions, int generationThreads) {
|
||||
this.sampler = sampler;
|
||||
if (dimensions == 2) {
|
||||
this.cache2D = Caffeine
|
||||
.newBuilder()
|
||||
.initialCapacity(0)
|
||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||
.build(vec -> sampler.noise(vec.seed, vec.x, vec.z));
|
||||
cache3D = null;
|
||||
cache3DDirv = null;
|
||||
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
||||
this.cache2DDirv = Caffeine
|
||||
.newBuilder()
|
||||
.initialCapacity(0)
|
||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||
.build(vec -> ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.z));
|
||||
} else {
|
||||
cache2DDirv = null;
|
||||
}
|
||||
} else {
|
||||
this.cache3D = Caffeine
|
||||
.newBuilder()
|
||||
.initialCapacity(0)
|
||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||
.build(vec -> sampler.noise(vec.seed, vec.x, vec.y, vec.z));
|
||||
cache2D = null;
|
||||
cache2DDirv = null;
|
||||
if (DerivativeNoiseSampler.isDifferentiable(sampler)) {
|
||||
this.cache3DDirv = Caffeine
|
||||
.newBuilder()
|
||||
.initialCapacity(0)
|
||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||
.build(vec -> ((DerivativeNoiseSampler) sampler).noised(vec.seed, vec.x, vec.y, vec.z));
|
||||
} else {
|
||||
cache3DDirv = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return DerivativeNoiseSampler.isDifferentiable(sampler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y) {
|
||||
return cache2DDirv.get(new DoubleSeededVector2(x, y, seed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y, double z) {
|
||||
return cache3DDirv.get(new DoubleSeededVector3(x, y, z, seed));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y) {
|
||||
DoubleSeededVector2 vec = new DoubleSeededVector2(x, y, seed);
|
||||
if (cache2DDirv != null && cache2DDirv.estimatedSize() != 0) {
|
||||
return cache2DDirv.get(vec)[0];
|
||||
}
|
||||
return cache2D.get(vec);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y, double z) {
|
||||
DoubleSeededVector3 vec = new DoubleSeededVector3(x, y, z, seed);
|
||||
if (cache3DDirv != null && cache3DDirv.estimatedSize() != 0) {
|
||||
return cache3DDirv.get(vec)[0];
|
||||
}
|
||||
return cache3D.get(vec);
|
||||
}
|
||||
|
||||
private record DoubleSeededVector3(double x, double y, double z, long seed) {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof DoubleSeededVector3 that) {
|
||||
return this.y == that.y && this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = (int) Double.doubleToLongBits(x);
|
||||
code = 31 * code + (int) Double.doubleToLongBits(y);
|
||||
code = 31 * code + (int) Double.doubleToLongBits(z);
|
||||
return 31 * code + (Long.hashCode(seed));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private record DoubleSeededVector2(double x, double z, long seed) {
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof DoubleSeededVector2 that) {
|
||||
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = (int) Double.doubleToLongBits(x);
|
||||
code = 31 * code + (int) Double.doubleToLongBits(z);
|
||||
return 31 * code + (Long.hashCode(seed));
|
||||
}
|
||||
}
|
||||
}
|
||||
-10
@@ -12,14 +12,4 @@ public class AdditionSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return left + right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
int dimensions = left.length;
|
||||
double[] out = new double[dimensions];
|
||||
for(int i = 0; i < dimensions; i++) {
|
||||
out[i] = left[i] + right[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-19
@@ -1,10 +1,9 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.arithmetic;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler {
|
||||
public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
||||
private final NoiseSampler left;
|
||||
private final NoiseSampler right;
|
||||
|
||||
@@ -13,11 +12,6 @@ public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return DerivativeNoiseSampler.isDifferentiable(left) && DerivativeNoiseSampler.isDifferentiable(right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y) {
|
||||
return operate(left.noise(seed, x, y), right.noise(seed, x, y));
|
||||
@@ -28,17 +22,5 @@ public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler
|
||||
return operate(left.noise(seed, x, y, z), right.noise(seed, x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y) {
|
||||
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y), ((DerivativeNoiseSampler)right).noised(seed, x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y, double z) {
|
||||
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y, z), ((DerivativeNoiseSampler)right).noised(seed, x, y, z));
|
||||
}
|
||||
|
||||
public abstract double operate(double left, double right);
|
||||
|
||||
public abstract double[] operateDerivative(double[] left, double[] right);
|
||||
}
|
||||
|
||||
-11
@@ -12,15 +12,4 @@ public class DivisionSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return left / right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
int dimensions = left.length;
|
||||
double[] out = new double[dimensions];
|
||||
out[0] = left[0] / right[0];
|
||||
for(int i = 1; i < dimensions; i++) {
|
||||
out[i] = (left[i] * right[0] - left[0] * right[i]) / (right[0] * right[0]);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
-7
@@ -12,11 +12,4 @@ public class MaxSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return Math.max(left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
double leftValue = left[0];
|
||||
double rightValue = right[0];
|
||||
return leftValue > rightValue ? left : right;
|
||||
}
|
||||
}
|
||||
|
||||
-7
@@ -12,11 +12,4 @@ public class MinSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return Math.min(left, right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
double leftValue = left[0];
|
||||
double rightValue = right[0];
|
||||
return leftValue < rightValue ? left : right;
|
||||
}
|
||||
}
|
||||
|
||||
-11
@@ -12,15 +12,4 @@ public class MultiplicationSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return left * right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
int dimensions = left.length;
|
||||
double[] out = new double[dimensions];
|
||||
out[0] = left[0] * right[0];
|
||||
for(int i = 1; i < dimensions; i++) {
|
||||
out[i] = left[i] * right[0] + left[0] * right[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
-10
@@ -12,14 +12,4 @@ public class SubtractionSampler extends BinaryArithmeticSampler {
|
||||
public double operate(double left, double right) {
|
||||
return left - right;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] operateDerivative(double[] left, double[] right) {
|
||||
int dimensions = left.length;
|
||||
double[] out = new double[dimensions];
|
||||
for(int i = 0; i < dimensions; i++) {
|
||||
out[i] = left[i] - right[i];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-12
@@ -197,9 +197,7 @@ public class CellularSampler extends NoiseFunction {
|
||||
private double jitterModifier = 1.0;
|
||||
|
||||
private NoiseSampler noiseLookup;
|
||||
|
||||
private boolean saltLookup;
|
||||
|
||||
|
||||
public CellularSampler() {
|
||||
noiseLookup = new OpenSimplex2Sampler();
|
||||
}
|
||||
@@ -219,11 +217,7 @@ public class CellularSampler extends NoiseFunction {
|
||||
public void setReturnType(ReturnType returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
public void setSaltLookup(boolean saltLookup) {
|
||||
this.saltLookup = saltLookup;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long sl, double x, double y) {
|
||||
int seed = (int) sl;
|
||||
@@ -292,8 +286,8 @@ public class CellularSampler extends NoiseFunction {
|
||||
case Distance2Sub -> distance1 - distance0 - 1;
|
||||
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
||||
case Distance2Div -> distance0 / distance1 - 1;
|
||||
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY);
|
||||
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY);
|
||||
case Distance3 -> distance2 - 1;
|
||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub -> distance2 - distance0 - 1;
|
||||
@@ -383,8 +377,8 @@ public class CellularSampler extends NoiseFunction {
|
||||
case Distance2Sub -> distance1 - distance0 - 1;
|
||||
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
|
||||
case Distance2Div -> distance0 / distance1 - 1;
|
||||
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY, centerZ);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
|
||||
case NoiseLookup -> noiseLookup.noise(sl, centerX, centerY, centerZ);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
|
||||
case Distance3 -> distance2 - 1;
|
||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub -> distance2 - distance0 - 1;
|
||||
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
|
||||
|
||||
public abstract class DerivativeNoiseFunction extends NoiseFunction implements DerivativeNoiseSampler {
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y) {
|
||||
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y, double z) {
|
||||
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency, z * frequency);
|
||||
}
|
||||
|
||||
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y);
|
||||
|
||||
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y, double z);
|
||||
}
|
||||
-173
@@ -1,173 +0,0 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
|
||||
|
||||
public class PseudoErosionSampler extends NoiseFunction {
|
||||
public static final double TAU = 2.0 * Math.PI;
|
||||
private static final double HASH_X = 0.3183099f;
|
||||
private static final double HASH_Y = 0.3678794f;
|
||||
public final double gain;
|
||||
public final double lacunarity;
|
||||
public final double slopeStrength;
|
||||
public final double branchStrength;
|
||||
public final double erosionStrength;
|
||||
private final int octaves;
|
||||
private final double erosionFrequency;
|
||||
private final DerivativeNoiseSampler sampler;
|
||||
private final boolean slopeMask;
|
||||
private final double slopeMaskFullSq;
|
||||
private final double slopeMaskNoneSq;
|
||||
private final double jitter;
|
||||
private final double maxCellDistSq;
|
||||
private final double maxCellDistSqRecip;
|
||||
private final boolean averageErosionImpulses;
|
||||
|
||||
public PseudoErosionSampler(int octaves, double gain, double lacunarity, double slopeStrength, double branchStrength,
|
||||
double erosionStrength, double erosionFrequency, DerivativeNoiseSampler sampler,
|
||||
boolean slopeMask, double slopeMaskFull, double slopeMaskNone, double jitterModifier,
|
||||
boolean averageErosionImpulses) {
|
||||
this.octaves = octaves;
|
||||
this.gain = gain;
|
||||
this.lacunarity = lacunarity;
|
||||
this.slopeStrength = slopeStrength;
|
||||
this.branchStrength = branchStrength;
|
||||
this.erosionStrength = erosionStrength;
|
||||
this.erosionFrequency = erosionFrequency;
|
||||
this.sampler = sampler;
|
||||
this.slopeMask = slopeMask;
|
||||
// Square these values and maintain sign since they're compared to a
|
||||
// squared value, otherwise a sqrt would need to be used
|
||||
this.slopeMaskFullSq = slopeMaskFull * slopeMaskFull * Math.signum(slopeMaskFull);
|
||||
this.slopeMaskNoneSq = slopeMaskNone * slopeMaskNone * Math.signum((slopeMaskNone));
|
||||
this.jitter = 0.43701595 * jitterModifier;
|
||||
this.averageErosionImpulses = averageErosionImpulses;
|
||||
this.maxCellDistSq = 1 + jitter * jitter;
|
||||
this.maxCellDistSqRecip = 1 / maxCellDistSq;
|
||||
}
|
||||
|
||||
public static double hashX(double seed, double n) {
|
||||
// Swapped the components here
|
||||
double nx = HASH_X * n * seed;
|
||||
return -1.0f + 2.0f * fract(nx);
|
||||
}
|
||||
|
||||
public static double hashY(double seed, double n) {
|
||||
double ny = HASH_Y * n * seed;
|
||||
return -1.0f + 2.0f * fract(ny);
|
||||
}
|
||||
|
||||
public static double fract(double x) {
|
||||
return (x - Math.floor(x));
|
||||
}
|
||||
|
||||
public static double smoothstep(double edge0, double edge1, double x) {
|
||||
// Scale, bias and saturate x to 0..1 range
|
||||
x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
// Evaluate polynomial
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
public static double clamp(double x, double minVal, double maxVal) {
|
||||
return Math.max(minVal, Math.min(maxVal, x));
|
||||
}
|
||||
|
||||
public static double dot(double x1, double y1, double x2, double y2) {
|
||||
return x1 * x2 + y1 * y2;
|
||||
}
|
||||
|
||||
public double[] erosion(int seed, double x, double y, double dirX, double dirY) {
|
||||
int gridX = (int) Math.round(x);
|
||||
int gridY = (int) Math.round(y);
|
||||
double noise = 0.0f;
|
||||
double dirOutX = 0.0f;
|
||||
double dirOutY = 0.0f;
|
||||
double cumAmp = 0.0f;
|
||||
|
||||
for(int cellX = gridX - 1; cellX <= gridX + 1; cellX++) {
|
||||
for(int cellY = gridY - 1; cellY <= gridY + 1; cellY++) {
|
||||
double cellHash = hash(seed, cellX, cellY);
|
||||
double cellOffsetX = hashX(seed, cellHash) * jitter;
|
||||
double cellOffsetY = hashY(seed, cellHash) * jitter;
|
||||
double cellOriginDeltaX = (x - cellX) + cellOffsetX;
|
||||
double cellOriginDeltaY = (y - cellY) + cellOffsetY;
|
||||
double cellOriginDistSq = cellOriginDeltaX * cellOriginDeltaX + cellOriginDeltaY * cellOriginDeltaY;
|
||||
if(cellOriginDistSq > maxCellDistSq) continue; // Skip calculating cells too far away
|
||||
double ampTmp = (cellOriginDistSq * maxCellDistSqRecip) - 1;
|
||||
double amp = ampTmp * ampTmp; // Decrease cell amplitude further away
|
||||
cumAmp += amp;
|
||||
double directionalStrength = dot(cellOriginDeltaX, cellOriginDeltaY, dirX, dirY) * TAU;
|
||||
noise += MathUtil.cos(directionalStrength) * amp;
|
||||
double sinAngle = MathUtil.sin(directionalStrength) * amp;
|
||||
dirOutX -= sinAngle * (cellOriginDeltaX + dirX);
|
||||
dirOutY -= sinAngle * (cellOriginDeltaY + dirY);
|
||||
}
|
||||
}
|
||||
if(averageErosionImpulses && cumAmp != 0) {
|
||||
noise /= cumAmp;
|
||||
dirOutX /= cumAmp;
|
||||
dirOutY /= cumAmp;
|
||||
}
|
||||
return new double[]{ noise, dirOutX, dirOutY };
|
||||
}
|
||||
|
||||
public double heightMap(long seed, double x, double y) {
|
||||
double[] sample = sampler.noised(seed, x, y);
|
||||
double height = sample[0];
|
||||
double heightDirX = sample[1];
|
||||
double heightDirY = sample[2];
|
||||
|
||||
// Take the curl of the normal to get the gradient facing down the slope
|
||||
double baseDirX = heightDirY * slopeStrength;
|
||||
double baseDirY = -heightDirX * slopeStrength;
|
||||
|
||||
double erosion = 0.0f;
|
||||
double dirX = 0.0f;
|
||||
double dirY = 0.0f;
|
||||
double amp = 1.0f;
|
||||
double cumAmp = 0.0f;
|
||||
double freq = 1.0f;
|
||||
|
||||
// Stack erosion octaves
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double[] erosionResult = erosion((int) seed,
|
||||
x * freq * erosionFrequency,
|
||||
y * freq * erosionFrequency,
|
||||
baseDirX + dirY * branchStrength,
|
||||
baseDirY - dirX * branchStrength);
|
||||
erosion += erosionResult[0] * amp;
|
||||
dirX += erosionResult[1] * amp * freq;
|
||||
dirY += erosionResult[2] * amp * freq;
|
||||
cumAmp += amp;
|
||||
amp *= gain;
|
||||
freq *= lacunarity;
|
||||
}
|
||||
|
||||
// Normalize erosion noise
|
||||
erosion /= cumAmp;
|
||||
// [-1, 1] -> [0, 1]
|
||||
erosion = erosion * 0.5F + 0.5F;
|
||||
|
||||
// Without masking, erosion noise in areas with small gradients tend to produce mounds,
|
||||
// this reduces erosion amplitude towards smaller gradients to avoid this
|
||||
if(slopeMask) {
|
||||
double dirMagSq = dot(baseDirX, baseDirY, baseDirX, baseDirY);
|
||||
double flatness = smoothstep((double) slopeMaskNoneSq, slopeMaskFullSq, dirMagSq);
|
||||
erosion *= flatness;
|
||||
}
|
||||
|
||||
return height + erosion * erosionStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y) {
|
||||
return heightMap(seed, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y, double z) {
|
||||
return getNoiseRaw(seed, x, z);
|
||||
}
|
||||
}
|
||||
+2
-59
@@ -7,7 +7,6 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
|
||||
@@ -25,7 +24,7 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = input.noise(seed++, x, y);
|
||||
sum += noise * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise + 1, 2) * 0.5);
|
||||
amp *= MathUtil.lerp(1.0, Math.min(noise + 1, 2) * 0.5, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
@@ -43,63 +42,7 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = input.noise(seed++, x, y, z);
|
||||
sum += noise * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, (noise + 1) * 0.5);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return DerivativeNoiseSampler.isDifferentiable(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||
double[] sum = {0, 0, 0};
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
// This should only be called after `input` is verified as a `DerivativeNoiseSampler`
|
||||
// so this should be a safe cast
|
||||
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y);
|
||||
sum[0] += noise[0] * amp;
|
||||
|
||||
// Directional derivative of each octave can be subject to the same addition and product
|
||||
// as per derivative sum and product rules in order to produce the correct final derivative
|
||||
sum[1] += noise[1] * amp;
|
||||
sum[2] += noise[2] * amp;
|
||||
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise[0] + 1, 2) * 0.5);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||
double[] sum = {0, 0, 0, 0};
|
||||
double amp = fractalBounding;
|
||||
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y, z);
|
||||
sum[0] += noise[0] * amp;
|
||||
|
||||
// See comment in 2D version
|
||||
sum[1] += noise[1] * amp;
|
||||
sum[2] += noise[2] * amp;
|
||||
sum[3] += noise[3] * amp;
|
||||
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, (noise[0] + 1) * 0.5);
|
||||
amp *= MathUtil.lerp(1.0, (noise + 1) * 0.5, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
|
||||
+2
-17
@@ -7,11 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public abstract class FractalNoiseFunction extends DerivativeNoiseFunction {
|
||||
public abstract class FractalNoiseFunction extends NoiseFunction {
|
||||
protected final NoiseSampler input;
|
||||
protected double fractalBounding = 1 / 1.75;
|
||||
protected int octaves = 3;
|
||||
@@ -52,19 +52,4 @@ public abstract class FractalNoiseFunction extends DerivativeNoiseFunction {
|
||||
public void setWeightedStrength(double weightedStrength) {
|
||||
this.weightedStrength = weightedStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ public class PingPongSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = pingPong((input.noise(seed++, x, y) + 1) * pingPongStrength);
|
||||
sum += (noise - 0.5) * 2 * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, noise);
|
||||
amp *= MathUtil.lerp(1.0, noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
@@ -54,7 +54,7 @@ public class PingPongSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = pingPong((input.noise(seed++, x, y, z) + 1) * pingPongStrength);
|
||||
sum += (noise - 0.5) * 2 * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, noise);
|
||||
amp *= MathUtil.lerp(1.0, noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@ public class RidgedFractalSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = Math.abs(input.noise(seed++, x, y));
|
||||
sum += (noise * -2 + 1) * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise);
|
||||
amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
@@ -43,7 +43,7 @@ public class RidgedFractalSampler extends FractalNoiseFunction {
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double noise = Math.abs(input.noise(seed++, x, y, z));
|
||||
sum += (noise * -2 + 1) * amp;
|
||||
amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise);
|
||||
amp *= MathUtil.lerp(1.0, 1 - noise, weightedStrength);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
|
||||
-420
@@ -276,424 +276,4 @@ public class OpenSimplex2SSampler extends SimplexStyleSampler {
|
||||
|
||||
return value * 9.046026385208288;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long sl, double x, double y) {
|
||||
int seed = (int) sl;
|
||||
// 2D OpenSimplex2S case is a modified 2D simplex noise.
|
||||
|
||||
final double SQRT3 = 1.7320508075688772935274463415059;
|
||||
final double G2 = (3 - SQRT3) / 6;
|
||||
|
||||
final double F2 = 0.5f * (SQRT3 - 1);
|
||||
double s = (x + y) * F2;
|
||||
x += s;
|
||||
y += s;
|
||||
|
||||
|
||||
int i = (int) Math.floor(x);
|
||||
int j = (int) Math.floor(y);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
int i1 = i + PRIME_X;
|
||||
int j1 = j + PRIME_Y;
|
||||
|
||||
double t = (xi + yi) * G2;
|
||||
double x0 = xi - t;
|
||||
double y0 = yi - t;
|
||||
|
||||
double[] out = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
double a0 = (2.0 / 3.0) - x0 * x0 - y0 * y0;
|
||||
double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0;
|
||||
int gi0 = gradCoordIndex(seed, i, j);
|
||||
double gx0 = GRADIENTS_2_D[gi0], gy0 = GRADIENTS_2_D[gi0 | 1];
|
||||
double rampValue0 = gx0 * x0 + gy0 * y0;
|
||||
out[0] = aaaa0 * rampValue0;
|
||||
out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0;
|
||||
out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0;
|
||||
|
||||
|
||||
double a1 = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
|
||||
double x1 = x0 - (1 - 2 * G2);
|
||||
double y1 = y0 - (1 - 2 * G2);
|
||||
double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1;
|
||||
int gi1 = gradCoordIndex(seed, i1, j1);
|
||||
double gx1 = GRADIENTS_2_D[gi1], gy1 = GRADIENTS_2_D[gi1 | 1];
|
||||
double rampValue1 = gx1 * x1 + gy1 * y1;
|
||||
out[0] += aaaa1 * rampValue1;
|
||||
out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1;
|
||||
out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1;
|
||||
|
||||
// Nested conditionals were faster than compact bit logic/arithmetic.
|
||||
double xmyi = xi - yi;
|
||||
if(t > G2) {
|
||||
if(xi + xmyi > 1) {
|
||||
double x2 = x0 + (3 * G2 - 2);
|
||||
double y2 = y0 + (3 * G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i + (PRIME_X << 1), j + PRIME_Y);
|
||||
double gx2 = GRADIENTS_2_D[gi2 | 0], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + G2;
|
||||
double y2 = y0 + (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i, j + PRIME_Y);
|
||||
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
}
|
||||
|
||||
if(yi - xmyi > 1) {
|
||||
double x3 = x0 + (3 * G2 - 1);
|
||||
double y3 = y0 + (3 * G2 - 2);
|
||||
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
|
||||
if(a3 > 0) {
|
||||
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
|
||||
int gi3 = gradCoordIndex(seed, i + PRIME_X, j + (PRIME_Y << 1));
|
||||
double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1];
|
||||
double rampValue3 = gx3 * x3 + gy3 * y3;
|
||||
out[0] += aaaa3 * rampValue3;
|
||||
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3;
|
||||
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
|
||||
}
|
||||
} else {
|
||||
double x3 = x0 + (G2 - 1);
|
||||
double y3 = y0 + G2;
|
||||
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
|
||||
if(a3 > 0) {
|
||||
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
|
||||
int gi3 = gradCoordIndex(seed, i + PRIME_X, j);
|
||||
double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1];
|
||||
double rampValue3 = gx3 * x3 + gy3 * y3;
|
||||
out[0] += aaaa3 * rampValue3;
|
||||
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3;
|
||||
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(xi + xmyi < 0) {
|
||||
double x2 = x0 + (1 - G2);
|
||||
double y2 = y0 - G2;
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i - PRIME_X, j);
|
||||
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + (G2 - 1);
|
||||
double y2 = y0 + G2;
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i + PRIME_X, j);
|
||||
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
}
|
||||
|
||||
if(yi < xmyi) {
|
||||
double x2 = x0 - G2;
|
||||
double y2 = y0 - (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i, j - PRIME_Y);
|
||||
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
} else {
|
||||
double x2 = x0 + G2;
|
||||
double y2 = y0 + (G2 - 1);
|
||||
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
|
||||
if(a2 > 0) {
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i, j + PRIME_Y);
|
||||
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y2;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
|
||||
}
|
||||
}
|
||||
}
|
||||
out[0] *= 18.24196194486065;
|
||||
out[1] *= 18.24196194486065;
|
||||
out[2] *= 18.24196194486065;
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) {
|
||||
int seed = (int) sl;
|
||||
// 3D OpenSimplex2S case uses two offset rotated cube grids.
|
||||
final double R3 = (2.0 / 3.0);
|
||||
double r = (x + y + z) * R3; // Rotation, not skew
|
||||
x = r - x;
|
||||
y = r - y;
|
||||
z = r - z;
|
||||
|
||||
|
||||
int i = (int) Math.floor(x);
|
||||
int j = (int) Math.floor(y);
|
||||
int k = (int) Math.floor(z);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
double zi = z - k;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
k *= PRIME_Z;
|
||||
int seed2 = seed + 1293373;
|
||||
|
||||
int xNMask = (int) (-0.5 - xi);
|
||||
int yNMask = (int) (-0.5 - yi);
|
||||
int zNMask = (int) (-0.5 - zi);
|
||||
|
||||
double[] out = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
|
||||
double x0 = xi + xNMask;
|
||||
double y0 = yi + yNMask;
|
||||
double z0 = zi + zNMask;
|
||||
double a0 = 0.75 - x0 * x0 - y0 * y0 - z0 * z0;
|
||||
double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0;
|
||||
int gi0 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
|
||||
double gx0 = GRADIENTS_3D[gi0], gy0 = GRADIENTS_3D[gi0 | 1], gz0 = GRADIENTS_3D[gi0 | 2];
|
||||
double rampValue0 = gx0 * x0 + gy0 * y0 + gz0 * z0;
|
||||
out[0] = aaaa0 * rampValue0;
|
||||
out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0;
|
||||
out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0;
|
||||
out[3] = gz0 * aaaa0 - 8 * rampValue0 * aaa0 * z0;
|
||||
|
||||
double x1 = xi - 0.5;
|
||||
double y1 = yi - 0.5;
|
||||
double z1 = zi - 0.5;
|
||||
double a1 = 0.75 - x1 * x1 - y1 * y1 - z1 * z1;
|
||||
double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1;
|
||||
int gi1 = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + PRIME_Z);
|
||||
double gx1 = GRADIENTS_3D[gi1], gy1 = GRADIENTS_3D[gi1 | 1], gz1 = GRADIENTS_3D[gi1 | 2];
|
||||
double rampValue1 = gx1 * x1 + gy1 * y1 + gz1 * z1;
|
||||
out[0] += aaaa1 * rampValue1;
|
||||
out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1;
|
||||
out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1;
|
||||
out[3] += gz1 * aaaa1 - 8 * rampValue1 * aaa1 * z1;
|
||||
|
||||
double xAFlipMask0 = ((xNMask | 1) << 1) * x1;
|
||||
double yAFlipMask0 = ((yNMask | 1) << 1) * y1;
|
||||
double zAFlipMask0 = ((zNMask | 1) << 1) * z1;
|
||||
double xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0;
|
||||
double yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0;
|
||||
double zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0;
|
||||
|
||||
boolean skip5 = false;
|
||||
double a2 = xAFlipMask0 + a0;
|
||||
if(a2 > 0) {
|
||||
double x2 = x0 - (xNMask | 1);
|
||||
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
|
||||
int gi2 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
|
||||
double gx2 = GRADIENTS_3D[gi2], gy2 = GRADIENTS_3D[gi2 | 1], gz2 = GRADIENTS_3D[gi2 | 2];
|
||||
double rampValue2 = gx2 * x2 + gy2 * y0 + gz2 * z0;
|
||||
out[0] += aaaa2 * rampValue2;
|
||||
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
|
||||
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y0;
|
||||
out[3] += gz2 * aaaa2 - 8 * rampValue2 * aaa2 * z0;
|
||||
} else {
|
||||
double a3 = yAFlipMask0 + zAFlipMask0 + a0;
|
||||
if(a3 > 0) {
|
||||
double y3 = y0 - (yNMask | 1);
|
||||
double z3 = z0 - (zNMask | 1);
|
||||
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
|
||||
int gi3 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
|
||||
double gx3 = GRADIENTS_3D[gi3], gy3 = GRADIENTS_3D[gi3 | 1], gz3 = GRADIENTS_3D[gi3 | 2];
|
||||
double rampValue3 = gx3 * x0 + gy3 * y3 + gz3 * z3;
|
||||
out[0] += aaaa3 * rampValue3;
|
||||
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x0;
|
||||
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
|
||||
out[3] += gz3 * aaaa3 - 8 * rampValue3 * aaa3 * z3;
|
||||
}
|
||||
|
||||
double a4 = xAFlipMask1 + a1;
|
||||
if(a4 > 0) {
|
||||
double x4 = (xNMask | 1) + x1;
|
||||
double aa4 = a4 * a4, aaa4 = aa4 * a4, aaaa4 = aa4 * aa4;
|
||||
int gi4 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + PRIME_Z);
|
||||
double gx4 = GRADIENTS_3D[gi4], gy4 = GRADIENTS_3D[gi4 | 1], gz4 = GRADIENTS_3D[gi4 | 2];
|
||||
double rampValue4 = gx4 * x4 + gy4 * y1 + gz4 * z1;
|
||||
out[0] += aaaa4 * rampValue4;
|
||||
out[1] += gx4 * aaaa4 - 8 * rampValue4 * aaa4 * x4;
|
||||
out[2] += gy4 * aaaa4 - 8 * rampValue4 * aaa4 * y1;
|
||||
out[3] += gz4 * aaaa4 - 8 * rampValue4 * aaa4 * z1;
|
||||
skip5 = true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean skip9 = false;
|
||||
double a6 = yAFlipMask0 + a0;
|
||||
if(a6 > 0) {
|
||||
double y6 = y0 - (yNMask | 1);
|
||||
double aa6 = a6 * a6, aaa6 = aa6 * a6, aaaa6 = aa6 * aa6;
|
||||
int gi6 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
|
||||
double gx6 = GRADIENTS_3D[gi6], gy6 = GRADIENTS_3D[gi6 | 1], gz6 = GRADIENTS_3D[gi6 | 2];
|
||||
double rampValue6 = gx6 * x0 + gy6 * y6 + gz6 * z0;
|
||||
out[0] += aaaa6 * rampValue6;
|
||||
out[1] += gx6 * aaaa6 - 8 * rampValue6 * aaa6 * x0;
|
||||
out[2] += gy6 * aaaa6 - 8 * rampValue6 * aaa6 * y6;
|
||||
out[3] += gz6 * aaaa6 - 8 * rampValue6 * aaa6 * z0;
|
||||
} else {
|
||||
double a7 = xAFlipMask0 + zAFlipMask0 + a0;
|
||||
if(a7 > 0) {
|
||||
double x7 = x0 - (xNMask | 1);
|
||||
double z7 = z0 - (zNMask | 1);
|
||||
double aa7 = a7 * a7, aaa7 = aa7 * a7, aaaa7 = aa7 * aa7;
|
||||
int gi7 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
|
||||
double gx7 = GRADIENTS_3D[gi7], gy7 = GRADIENTS_3D[gi7 | 1], gz7 = GRADIENTS_3D[gi7 | 2];
|
||||
double rampValue7 = gx7 * x7 + gy7 * y0 + gz7 * z7;
|
||||
out[0] += aaaa7 * rampValue7;
|
||||
out[1] += gx7 * aaaa7 - 8 * rampValue7 * aaa7 * x7;
|
||||
out[2] += gy7 * aaaa7 - 8 * rampValue7 * aaa7 * y0;
|
||||
out[3] += gz7 * aaaa7 - 8 * rampValue7 * aaa7 * z7;
|
||||
}
|
||||
|
||||
double a8 = yAFlipMask1 + a1;
|
||||
if(a8 > 0) {
|
||||
double y8 = (yNMask | 1) + y1;
|
||||
double aa8 = a8 * a8, aaa8 = aa8 * a8, aaaa8 = aa8 * aa8;
|
||||
int gi8 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z);
|
||||
double gx8 = GRADIENTS_3D[gi8], gy8 = GRADIENTS_3D[gi8 | 1], gz8 = GRADIENTS_3D[gi8 | 2];
|
||||
double rampValue8 = gx8 * x1 + gy8 * y8 + gz8 * z1;
|
||||
out[0] += aaaa8 * rampValue8;
|
||||
out[1] += gx8 * aaaa8 - 8 * rampValue8 * aaa8 * x1;
|
||||
out[2] += gy8 * aaaa8 - 8 * rampValue8 * aaa8 * y8;
|
||||
out[3] += gz8 * aaaa8 - 8 * rampValue8 * aaa8 * z1;
|
||||
skip9 = true;
|
||||
}
|
||||
}
|
||||
|
||||
boolean skipD = false;
|
||||
double aA = zAFlipMask0 + a0;
|
||||
if(aA > 0) {
|
||||
double zA = z0 - (zNMask | 1);
|
||||
double aaA = aA * aA, aaaA = aaA * aA, aaaaA = aaA * aaA;
|
||||
int giA = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
|
||||
double gxA = GRADIENTS_3D[giA], gyA = GRADIENTS_3D[giA | 1], gzA = GRADIENTS_3D[giA | 2];
|
||||
double rampValueA = gxA * x0 + gyA * y0 + gzA * zA;
|
||||
out[0] += aaaaA * rampValueA;
|
||||
out[1] += gxA * aaaaA - 8 * rampValueA * aaaA * x0;
|
||||
out[2] += gyA * aaaaA - 8 * rampValueA * aaaA * y0;
|
||||
out[3] += gzA * aaaaA - 8 * rampValueA * aaaA * zA;
|
||||
} else {
|
||||
double aB = xAFlipMask0 + yAFlipMask0 + a0;
|
||||
if(aB > 0) {
|
||||
double xB = x0 - (xNMask | 1);
|
||||
double yB = y0 - (yNMask | 1);
|
||||
double aaB = aB * aB, aaaB = aaB * aB, aaaaB = aaB * aaB;
|
||||
int giB = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
|
||||
double gxB = GRADIENTS_3D[giB], gyB = GRADIENTS_3D[giB | 1], gzB = GRADIENTS_3D[giB | 2];
|
||||
double rampValueB = gxB * xB + gyB * yB + gzB * z0;
|
||||
out[0] += aaaaB * rampValueB;
|
||||
out[1] += gxB * aaaaB - 8 * rampValueB * aaaB * xB;
|
||||
out[2] += gyB * aaaaB - 8 * rampValueB * aaaB * yB;
|
||||
out[3] += gzB * aaaaB - 8 * rampValueB * aaaB * z0;
|
||||
}
|
||||
|
||||
double aC = zAFlipMask1 + a1;
|
||||
if(aC > 0) {
|
||||
double zC = (zNMask | 1) + z1;
|
||||
double aaC = aC * aC, aaaC = aaC * aC, aaaaC = aaC * aaC;
|
||||
int giC = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)));
|
||||
double gxC = GRADIENTS_3D[giC], gyC = GRADIENTS_3D[giC | 1], gzC = GRADIENTS_3D[giC | 2];
|
||||
double rampValueC = gxC * x1 + gyC * y1 + gzC * zC;
|
||||
out[0] += aaaaC * rampValueC;
|
||||
out[1] += gxC * aaaaC - 8 * rampValueC * aaaC * x1;
|
||||
out[2] += gyC * aaaaC - 8 * rampValueC * aaaC * y1;
|
||||
out[3] += gzC * aaaaC - 8 * rampValueC * aaaC * zC;
|
||||
skipD = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip5) {
|
||||
double a5 = yAFlipMask1 + zAFlipMask1 + a1;
|
||||
if(a5 > 0) {
|
||||
double y5 = (yNMask | 1) + y1;
|
||||
double z5 = (zNMask | 1) + z1;
|
||||
double aa5 = a5 * a5, aaa5 = aa5 * a5, aaaa5 = aa5 * aa5;
|
||||
int gi5 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + (zNMask & (PRIME_Z << 1)));
|
||||
double gx5 = GRADIENTS_3D[gi5], gy5 = GRADIENTS_3D[gi5 | 1], gz5 = GRADIENTS_3D[gi5 | 2];
|
||||
double rampValue5 = gx5 * x1 + gy5 * y5 + gz5 * z5;
|
||||
out[0] += aaaa5 * rampValue5;
|
||||
out[1] += gx5 * aaaa5 - 8 * rampValue5 * aaa5 * x1;
|
||||
out[2] += gy5 * aaaa5 - 8 * rampValue5 * aaa5 * y5;
|
||||
out[3] += gz5 * aaaa5 - 8 * rampValue5 * aaa5 * z5;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skip9) {
|
||||
double a9 = xAFlipMask1 + zAFlipMask1 + a1;
|
||||
if(a9 > 0) {
|
||||
double x9 = (xNMask | 1) + x1;
|
||||
double z9 = (zNMask | 1) + z1;
|
||||
double aa9 = a9 * a9, aaa9 = aa9 * a9, aaaa9 = aa9 * aa9;
|
||||
int gi9 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)));
|
||||
double gx9 = GRADIENTS_3D[gi9], gy9 = GRADIENTS_3D[gi9 | 1], gz9 = GRADIENTS_3D[gi9 | 2];
|
||||
double rampValue9 = gx9 * x9 + gy9 * y1 + gz9 * z9;
|
||||
out[0] += aaaa9 * rampValue9;
|
||||
out[1] += gx9 * aaaa9 - 8 * rampValue9 * aaa9 * x9;
|
||||
out[2] += gy9 * aaaa9 - 8 * rampValue9 * aaa9 * y1;
|
||||
out[3] += gz9 * aaaa9 - 8 * rampValue9 * aaa9 * z9;
|
||||
}
|
||||
}
|
||||
|
||||
if(!skipD) {
|
||||
double aD = xAFlipMask1 + yAFlipMask1 + a1;
|
||||
if(aD > 0) {
|
||||
double xD = (xNMask | 1) + x1;
|
||||
double yD = (yNMask | 1) + y1;
|
||||
double aaD = aD * aD, aaaD = aaD * aD, aaaaD = aaD * aaD;
|
||||
int giD = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z);
|
||||
double gxD = GRADIENTS_3D[giD], gyD = GRADIENTS_3D[giD | 1], gzD = GRADIENTS_3D[giD | 2];
|
||||
double rampValueD = gxD * xD + gyD * yD + gzD * z1;
|
||||
out[0] += aaaaD * rampValueD;
|
||||
out[1] += gxD * aaaaD - 8 * rampValueD * aaaD * xD;
|
||||
out[2] += gyD * aaaaD - 8 * rampValueD * aaaD * yD;
|
||||
out[3] += gzD * aaaaD - 8 * rampValueD * aaaD * z1;
|
||||
}
|
||||
}
|
||||
|
||||
out[0] *= 9.046026385208288;
|
||||
out[1] *= 9.046026385208288;
|
||||
out[2] *= 9.046026385208288;
|
||||
out[3] *= 9.046026385208288;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-214
@@ -37,37 +37,41 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
|
||||
double value = 0;
|
||||
double n0, n1, n2;
|
||||
|
||||
double a = 0.5 - x0 * x0 - y0 * y0;
|
||||
if(a > 0) {
|
||||
value = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
|
||||
if(a <= 0) n0 = 0;
|
||||
else {
|
||||
n0 = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
|
||||
}
|
||||
|
||||
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
|
||||
if(c > 0) {
|
||||
if(c <= 0) n2 = 0;
|
||||
else {
|
||||
double x2 = x0 + (2 * G2 - 1);
|
||||
double y2 = y0 + (2 * G2 - 1);
|
||||
value += (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
|
||||
n2 = (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
|
||||
}
|
||||
|
||||
if(y0 > x0) {
|
||||
double x1 = x0 + G2;
|
||||
double y1 = y0 + (G2 - 1);
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b > 0) {
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
|
||||
}
|
||||
} else {
|
||||
double x1 = x0 + (G2 - 1);
|
||||
double y1 = y0 + G2;
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b > 0) {
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
return value * 99.83685446303647f;
|
||||
return (n0 + n1 + n2) * 99.83685446303647f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,208 +157,4 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
|
||||
|
||||
return value * 32.69428253173828125;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long sl, double x, double y) {
|
||||
int seed = (int) sl;
|
||||
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
|
||||
final double G2 = (3 - SQRT3) / 6;
|
||||
|
||||
final double F2 = 0.5f * (SQRT3 - 1);
|
||||
double s = (x + y) * F2;
|
||||
x += s;
|
||||
y += s;
|
||||
|
||||
|
||||
int i = (int) Math.floor(x);
|
||||
int j = (int) Math.floor(y);
|
||||
double xi = x - i;
|
||||
double yi = y - j;
|
||||
|
||||
double t = (xi + yi) * G2;
|
||||
double x0 = xi - t;
|
||||
double y0 = yi - t;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
|
||||
double[] out = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
double a = 0.5 - x0 * x0 - y0 * y0;
|
||||
if(a > 0) {
|
||||
double aa = a * a, aaa = aa * a, aaaa = aa * aa;
|
||||
int gi = gradCoordIndex(seed, i, j);
|
||||
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
|
||||
double rampValue = gx * x0 + gy * y0;
|
||||
out[0] += aaaa * rampValue;
|
||||
out[1] += gx * aaaa - 8 * rampValue * aaa * x0;
|
||||
out[2] += gy * aaaa - 8 * rampValue * aaa * y0;
|
||||
}
|
||||
|
||||
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
|
||||
if(c > 0) {
|
||||
double x2 = x0 + (2 * G2 - 1);
|
||||
double y2 = y0 + (2 * G2 - 1);
|
||||
double cc = c * c, ccc = cc * c, cccc = cc * cc;
|
||||
int gi = gradCoordIndex(seed, i + PRIME_X, j + PRIME_Y);
|
||||
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
|
||||
double rampValue = gx * x2 + gy * y2;
|
||||
out[0] += cccc * rampValue;
|
||||
out[1] += gx * cccc - 8 * rampValue * ccc * x2;
|
||||
out[2] += gy * cccc - 8 * rampValue * ccc * y2;
|
||||
}
|
||||
|
||||
if(y0 > x0) {
|
||||
double x1 = x0 + G2;
|
||||
double y1 = y0 + (G2 - 1);
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b > 0) {
|
||||
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
|
||||
int gi = gradCoordIndex(seed, i, j + PRIME_Y);
|
||||
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
|
||||
double rampValue = gx * x1 + gy * y1;
|
||||
out[0] += bbbb * rampValue;
|
||||
out[1] += gx * bbbb - 8 * rampValue * bbb * x1;
|
||||
out[2] += gy * bbbb - 8 * rampValue * bbb * y1;
|
||||
}
|
||||
} else {
|
||||
double x1 = x0 + (G2 - 1);
|
||||
double y1 = y0 + G2;
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b > 0) {
|
||||
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
|
||||
int gi = gradCoordIndex(seed, i + PRIME_X, j);
|
||||
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
|
||||
double rampValue = gx * x1 + gy * y1;
|
||||
out[0] += bbbb * rampValue;
|
||||
out[1] += gx * bbbb - 8 * rampValue * bbb * x1;
|
||||
out[2] += gy * bbbb - 8 * rampValue * bbb * y1;
|
||||
}
|
||||
}
|
||||
|
||||
out[0] *= 99.83685446303647f;
|
||||
out[1] *= 99.83685446303647f;
|
||||
out[2] *= 99.83685446303647f;
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) {
|
||||
int seed = (int) sl;
|
||||
// 3D OpenSimplex2Sampler case uses two offset rotated cube grids.
|
||||
final double R3 = (2.0 / 3.0);
|
||||
double r = (x + y + z) * R3; // Rotation, not skew
|
||||
x = r - x;
|
||||
y = r - y;
|
||||
z = r - z;
|
||||
|
||||
|
||||
int i = (int) Math.round(x);
|
||||
int j = (int) Math.round(y);
|
||||
int k = (int) Math.round(z);
|
||||
double x0 = x - i;
|
||||
double y0 = y - j;
|
||||
double z0 = z - k;
|
||||
|
||||
int xNSign = (int) (-1.0 - x0) | 1;
|
||||
int yNSign = (int) (-1.0 - y0) | 1;
|
||||
int zNSign = (int) (-1.0 - z0) | 1;
|
||||
|
||||
double ax0 = xNSign * -x0;
|
||||
double ay0 = yNSign * -y0;
|
||||
double az0 = zNSign * -z0;
|
||||
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
k *= PRIME_Z;
|
||||
|
||||
double[] out = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
double a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
|
||||
|
||||
for(int l = 0; ; l++) {
|
||||
if(a > 0) {
|
||||
double aa = a * a, aaa = aa * a, aaaa = aa * aa;
|
||||
int gi = gradCoordIndex(seed, i, j, k);
|
||||
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
|
||||
double rampValue = gx * x0 + gy * y0 + gz * z0;
|
||||
out[0] += aaaa * rampValue;
|
||||
out[1] += gx * aaaa - 8 * rampValue * aaa * x0;
|
||||
out[1] += gy * aaaa - 8 * rampValue * aaa * y0;
|
||||
out[2] += gz * aaaa - 8 * rampValue * aaa * z0;
|
||||
}
|
||||
|
||||
if(ax0 >= ay0 && ax0 >= az0) {
|
||||
double b = a + ax0 + ax0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
|
||||
int gi = gradCoordIndex(seed, i - xNSign * PRIME_X, j, k);
|
||||
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
|
||||
double rampValue = gx * (x0 + xNSign) + gy * y0 + gz * z0;
|
||||
out[0] += bbbb * rampValue;
|
||||
out[1] += gx * bbbb - 8 * rampValue * bbb * (x0 + xNSign);
|
||||
out[1] += gy * bbbb - 8 * rampValue * bbb * y0;
|
||||
out[2] += gz * bbbb - 8 * rampValue * bbb * z0;
|
||||
}
|
||||
} else if(ay0 > ax0 && ay0 >= az0) {
|
||||
double b = a + ay0 + ay0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
|
||||
int gi = gradCoordIndex(seed, i, j - yNSign * PRIME_Y, k);
|
||||
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
|
||||
double rampValue = gx * x0 + gy * (y0 + yNSign) + gz * z0;
|
||||
out[0] += bbbb * rampValue;
|
||||
out[1] += gx * bbbb - 8 * rampValue * bbb * x0;
|
||||
out[1] += gy * bbbb - 8 * rampValue * bbb * (y0 + yNSign);
|
||||
out[2] += gz * bbbb - 8 * rampValue * bbb * z0;
|
||||
}
|
||||
} else {
|
||||
double b = a + az0 + az0;
|
||||
if(b > 1) {
|
||||
b -= 1;
|
||||
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
|
||||
int gi = gradCoordIndex(seed, i, j, k - zNSign * PRIME_Z);
|
||||
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
|
||||
double rampValue = gx * x0 + gy * y0 + gz * (z0 + zNSign);
|
||||
out[0] += bbbb * rampValue;
|
||||
out[1] += gx * bbbb - 8 * rampValue * bbb * x0;
|
||||
out[1] += gy * bbbb - 8 * rampValue * bbb * y0;
|
||||
out[2] += gz * bbbb - 8 * rampValue * bbb * (z0 + zNSign);
|
||||
}
|
||||
}
|
||||
|
||||
if(l == 1) break;
|
||||
|
||||
ax0 = 0.5 - ax0;
|
||||
ay0 = 0.5 - ay0;
|
||||
az0 = 0.5 - az0;
|
||||
|
||||
x0 = xNSign * ax0;
|
||||
y0 = yNSign * ay0;
|
||||
z0 = zNSign * az0;
|
||||
|
||||
a += (0.75 - ax0) - (ay0 + az0);
|
||||
|
||||
i += (xNSign >> 1) & PRIME_X;
|
||||
j += (yNSign >> 1) & PRIME_Y;
|
||||
k += (zNSign >> 1) & PRIME_Z;
|
||||
|
||||
xNSign = -xNSign;
|
||||
yNSign = -yNSign;
|
||||
zNSign = -zNSign;
|
||||
|
||||
seed = ~seed;
|
||||
}
|
||||
out[0] *= 32.69428253173828125;
|
||||
out[1] *= 32.69428253173828125;
|
||||
out[2] *= 32.69428253173828125;
|
||||
out[3] *= 32.69428253173828125;
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -33,10 +33,10 @@ public class PerlinSampler extends SimplexStyleSampler {
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
|
||||
double xf0 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0));
|
||||
double xf1 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1));
|
||||
double xf0 = MathUtil.lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs);
|
||||
double xf1 = MathUtil.lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs);
|
||||
|
||||
return MathUtil.lerp(ys, xf0, xf1) * 1.4247691104677813;
|
||||
return MathUtil.lerp(xf0, xf1, ys) * 1.4247691104677813;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,14 +64,14 @@ public class PerlinSampler extends SimplexStyleSampler {
|
||||
int y1 = y0 + PRIME_Y;
|
||||
int z1 = z0 + PRIME_Z;
|
||||
|
||||
double xf00 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0));
|
||||
double xf10 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0));
|
||||
double xf01 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1));
|
||||
double xf11 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1));
|
||||
double xf00 = MathUtil.lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
|
||||
double xf10 = MathUtil.lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
|
||||
double xf01 = MathUtil.lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
|
||||
double xf11 = MathUtil.lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
|
||||
|
||||
double yf0 = MathUtil.lerp(ys, xf00, xf10);
|
||||
double yf1 = MathUtil.lerp(ys, xf01, xf11);
|
||||
double yf0 = MathUtil.lerp(xf00, xf10, ys);
|
||||
double yf1 = MathUtil.lerp(xf01, xf11, ys);
|
||||
|
||||
return MathUtil.lerp(zs, yf0, yf1) * 0.964921414852142333984375;
|
||||
return MathUtil.lerp(yf0, yf1, zs) * 0.964921414852142333984375;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-36
@@ -7,13 +7,13 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.samplers.noise.simplex;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract NoiseSampler implementation for simplex-style noise functions.
|
||||
*/
|
||||
public abstract class SimplexStyleSampler extends DerivativeNoiseFunction {
|
||||
public abstract class SimplexStyleSampler extends NoiseFunction {
|
||||
protected static final double[] GRADIENTS_2_D = {
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
@@ -79,53 +79,26 @@ public abstract class SimplexStyleSampler extends DerivativeNoiseFunction {
|
||||
1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0
|
||||
};
|
||||
|
||||
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed) {
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 127 << 1;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
|
||||
int index = gradCoordIndex(seed, xPrimed, yPrimed);
|
||||
|
||||
double xg = GRADIENTS_2_D[index];
|
||||
double yg = GRADIENTS_2_D[index | 1];
|
||||
double xg = GRADIENTS_2_D[hash];
|
||||
double yg = GRADIENTS_2_D[hash | 1];
|
||||
|
||||
return xd * xg + yd * yg;
|
||||
}
|
||||
|
||||
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed, int zPrimed) {
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 63 << 2;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
|
||||
int index = gradCoordIndex(seed, xPrimed, yPrimed, zPrimed);
|
||||
|
||||
double xg = GRADIENTS_3D[index];
|
||||
double yg = GRADIENTS_3D[index | 1];
|
||||
double zg = GRADIENTS_3D[index | 2];
|
||||
double xg = GRADIENTS_3D[hash];
|
||||
double yg = GRADIENTS_3D[hash | 1];
|
||||
double zg = GRADIENTS_3D[hash | 2];
|
||||
|
||||
return xd * xg + yd * yg + zd * zg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
|
||||
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -25,10 +25,10 @@ public class ValueSampler extends ValueStyleNoise {
|
||||
int x1 = x0 + PRIME_X;
|
||||
int y1 = y0 + PRIME_Y;
|
||||
|
||||
double xf0 = MathUtil.lerp(xs, valCoord(seed, x0, y0), valCoord(seed, x1, y0));
|
||||
double xf1 = MathUtil.lerp(xs, valCoord(seed, x0, y1), valCoord(seed, x1, y1));
|
||||
double xf0 = MathUtil.lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs);
|
||||
double xf1 = MathUtil.lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs);
|
||||
|
||||
return MathUtil.lerp(ys, xf0, xf1);
|
||||
return MathUtil.lerp(xf0, xf1, ys);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,14 +49,14 @@ public class ValueSampler extends ValueStyleNoise {
|
||||
int y1 = y0 + PRIME_Y;
|
||||
int z1 = z0 + PRIME_Z;
|
||||
|
||||
double xf00 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0));
|
||||
double xf10 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0));
|
||||
double xf01 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1));
|
||||
double xf11 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1));
|
||||
double xf00 = MathUtil.lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs);
|
||||
double xf10 = MathUtil.lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs);
|
||||
double xf01 = MathUtil.lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs);
|
||||
double xf11 = MathUtil.lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs);
|
||||
|
||||
double yf0 = MathUtil.lerp(ys, xf00, xf10);
|
||||
double yf1 = MathUtil.lerp(ys, xf01, xf11);
|
||||
double yf0 = MathUtil.lerp(xf00, xf10, ys);
|
||||
double yf1 = MathUtil.lerp(xf01, xf11, ys);
|
||||
|
||||
return MathUtil.lerp(zs, yf0, yf1);
|
||||
return MathUtil.lerp(yf0, yf1, zs);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -11,6 +11,13 @@ import com.dfsek.tectonic.api.config.template.dynamic.DynamicTemplate;
|
||||
import com.dfsek.tectonic.api.config.template.dynamic.DynamicValue;
|
||||
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures;
|
||||
import com.dfsek.terra.addons.generation.feature.config.FeatureStageTemplate;
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
@@ -28,9 +35,6 @@ import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
|
||||
public class FeatureGenerationAddon implements AddonInitializer {
|
||||
public static final TypeKey<Supplier<ObjectTemplate<GenerationStage>>> STAGE_TYPE_KEY = new TypeKey<>() {
|
||||
|
||||
+5
-16
@@ -7,9 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.generation.feature;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.generation.feature.config.BiomeFeatures;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.properties.PropertyKey;
|
||||
import com.dfsek.terra.api.registry.key.StringIdentifiable;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
@@ -19,9 +21,6 @@ import com.dfsek.terra.api.world.chunk.generation.ProtoWorld;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.Column;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class FeatureGenerationStage implements GenerationStage, StringIdentifiable {
|
||||
private final Platform platform;
|
||||
@@ -32,20 +31,13 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
||||
|
||||
private final int resolution;
|
||||
private final PropertyKey<BiomeFeatures> biomeFeaturesKey;
|
||||
private final NoiseSampler blendSampler;
|
||||
private final boolean doBlending;
|
||||
private final double blendAmplitude;
|
||||
|
||||
public FeatureGenerationStage(Platform platform, String id, int resolution, PropertyKey<BiomeFeatures> biomeFeaturesKey,
|
||||
NoiseSampler blendSampler, double blendAmplitude) {
|
||||
public FeatureGenerationStage(Platform platform, String id, int resolution, PropertyKey<BiomeFeatures> biomeFeaturesKey) {
|
||||
this.platform = platform;
|
||||
this.id = id;
|
||||
this.profile = "feature_stage:" + id;
|
||||
this.resolution = resolution;
|
||||
this.biomeFeaturesKey = biomeFeaturesKey;
|
||||
this.blendSampler = blendSampler;
|
||||
this.doBlending = blendAmplitude != 0d;
|
||||
this.blendAmplitude = blendAmplitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,10 +52,7 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
||||
int tx = cx + chunkX;
|
||||
int tz = cz + chunkZ;
|
||||
world.getBiomeProvider()
|
||||
.getColumn(
|
||||
tx + (doBlending ? (int) (blendSampler.noise(seed, tx, tz) * blendAmplitude) : 0),
|
||||
tz + (doBlending ? (int) (blendSampler.noise(seed + 1, tx, tz) * blendAmplitude) : 0),
|
||||
world)
|
||||
.getColumn(tx, tz, world)
|
||||
.forRanges(resolution, (min, max, biome) -> {
|
||||
for(int subChunkX = 0; subChunkX < resolution; subChunkX++) {
|
||||
for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) {
|
||||
|
||||
+1
-20
@@ -8,7 +8,6 @@ import com.dfsek.tectonic.api.exception.ValidationException;
|
||||
|
||||
import com.dfsek.terra.addons.generation.feature.FeatureGenerationStage;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.properties.PropertyKey;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
|
||||
@@ -23,24 +22,6 @@ public class FeatureStageTemplate implements ObjectTemplate<GenerationStage>, Va
|
||||
@Default
|
||||
private int resolution = 4;
|
||||
|
||||
@Value("blend.sampler")
|
||||
@Default
|
||||
private NoiseSampler blendSampler = new NoiseSampler() {
|
||||
@Override
|
||||
public double noise(long seed, double x, double y) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y, double z) {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
@Value("blend.amplitude")
|
||||
@Default
|
||||
private double blendAmplitude = 0d;
|
||||
|
||||
public FeatureStageTemplate(Platform platform, PropertyKey<BiomeFeatures> biomeFeaturesKey) {
|
||||
this.platform = platform;
|
||||
this.biomeFeaturesKey = biomeFeaturesKey;
|
||||
@@ -49,7 +30,7 @@ public class FeatureStageTemplate implements ObjectTemplate<GenerationStage>, Va
|
||||
|
||||
@Override
|
||||
public FeatureGenerationStage get() {
|
||||
return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey, blendSampler, blendAmplitude);
|
||||
return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+19
-4
@@ -11,12 +11,16 @@ import com.dfsek.tectonic.yaml.YamlConfiguration;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
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.ConfigurationDiscoveryEvent;
|
||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||
import com.dfsek.terra.api.inject.annotations.Inject;
|
||||
import com.dfsek.terra.api.util.FileUtil;
|
||||
|
||||
|
||||
public class YamlAddon implements AddonInitializer {
|
||||
@@ -33,10 +37,21 @@ public class YamlAddon implements AddonInitializer {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigurationDiscoveryEvent.class)
|
||||
.then(event -> event.getLoader().open("", ".yml").thenEntries(entries -> entries.forEach(entry -> {
|
||||
LOGGER.debug("Discovered config {}", entry.getKey());
|
||||
event.register(entry.getKey(), new YamlConfiguration(entry.getValue(), entry.getKey()));
|
||||
})).close())
|
||||
.then(event -> {
|
||||
try {
|
||||
FileUtil.filesWithExtension(event.getPack().getRootPath(), ".yml")
|
||||
.forEach((key, value) -> {
|
||||
LOGGER.debug("Discovered config {}", key);
|
||||
try {
|
||||
event.register(key, new YamlConfiguration(Files.newInputStream(value), key));
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException("Failed to load config " + key, e);
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException("Error occurred while reading config pack files", e);
|
||||
}
|
||||
})
|
||||
.failThrough();
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -60,8 +60,8 @@ public class ImageLibraryAddon implements AddonInitializer {
|
||||
.then(event -> {
|
||||
ConfigPack pack = event.getPack();
|
||||
CheckedRegistry<Supplier<ObjectTemplate<Image>>> imageRegistry = pack.getOrCreateRegistry(IMAGE_REGISTRY_KEY);
|
||||
imageRegistry.register(addon.key("BITMAP"), () -> new ImageTemplate(pack.getLoader(), pack));
|
||||
imageRegistry.register(addon.key("STITCHED_BITMAP"), () -> new StitchedImageTemplate(pack.getLoader(), pack));
|
||||
imageRegistry.register(addon.key("BITMAP"), () -> new ImageTemplate(pack));
|
||||
imageRegistry.register(addon.key("STITCHED_BITMAP"), () -> new StitchedImageTemplate(pack));
|
||||
})
|
||||
.then(event -> {
|
||||
event.getPack()
|
||||
|
||||
+8
-16
@@ -4,8 +4,10 @@ import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.dfsek.terra.addons.image.config.ImageLibraryPackConfigTemplate;
|
||||
@@ -13,7 +15,6 @@ import com.dfsek.terra.addons.image.image.BufferedImageWrapper;
|
||||
import com.dfsek.terra.addons.image.image.Image;
|
||||
import com.dfsek.terra.addons.image.image.SuppliedImage;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
import com.dfsek.terra.api.util.generic.Lazy;
|
||||
|
||||
@@ -22,13 +23,13 @@ import com.dfsek.terra.api.util.generic.Lazy;
|
||||
* Cache prevents configs from loading the same image multiple times into memory
|
||||
*/
|
||||
record ImageCache(LoadingCache<String, Image> cache) implements Properties {
|
||||
public static Image load(String path, ConfigPack pack, Loader files) throws IOException {
|
||||
public static Image load(String path, ConfigPack pack) throws IOException {
|
||||
ImageLibraryPackConfigTemplate config = pack.getContext().get(ImageLibraryPackConfigTemplate.class);
|
||||
ImageCache images;
|
||||
if(!pack.getContext().has(ImageCache.class)) {
|
||||
var cacheBuilder = Caffeine.newBuilder();
|
||||
if(config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS);
|
||||
images = new ImageCache(cacheBuilder.build(s -> loadImage(s, files)));
|
||||
images = new ImageCache(cacheBuilder.build(s -> loadImage(s, pack.getRootPath())));
|
||||
pack.getContext().put(images);
|
||||
} else images = pack.getContext().get(ImageCache.class);
|
||||
|
||||
@@ -45,17 +46,8 @@ record ImageCache(LoadingCache<String, Image> cache) implements Properties {
|
||||
return images.cache.get(path);
|
||||
}
|
||||
|
||||
private static Image loadImage(String path, Loader files) throws IOException {
|
||||
try {
|
||||
return new BufferedImageWrapper(ImageIO.read(files.get(path)));
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new IllegalArgumentException("Unable to load image (image might be too large?)", e);
|
||||
} catch(IOException e) {
|
||||
if(e instanceof FileNotFoundException) {
|
||||
// Rethrow using nicer message
|
||||
throw new IOException("Unable to load image: No such file or directory: " + path, e);
|
||||
}
|
||||
throw new IOException("Unable to load image", e);
|
||||
}
|
||||
private static Image loadImage(String path, Path directory) throws IOException {
|
||||
InputStream is = Files.newInputStream(directory.resolve(path));
|
||||
return new BufferedImageWrapper(ImageIO.read(is));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -7,25 +7,22 @@ import java.io.IOException;
|
||||
|
||||
import com.dfsek.terra.addons.image.image.Image;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
|
||||
public class ImageTemplate implements ObjectTemplate<Image> {
|
||||
|
||||
private final Loader files;
|
||||
private final ConfigPack pack;
|
||||
@Value("path")
|
||||
private String path;
|
||||
|
||||
public ImageTemplate(Loader files, ConfigPack pack) {
|
||||
this.files = files;
|
||||
public ImageTemplate(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image get() {
|
||||
try {
|
||||
return ImageCache.load(path, pack, files);
|
||||
return ImageCache.load(path, pack);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
+2
-5
@@ -11,12 +11,10 @@ import java.io.IOException;
|
||||
import com.dfsek.terra.addons.image.image.Image;
|
||||
import com.dfsek.terra.addons.image.image.StitchedImage;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
|
||||
public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedConfigTemplate {
|
||||
|
||||
private final Loader files;
|
||||
private final ConfigPack pack;
|
||||
@Value("path-format")
|
||||
private String path;
|
||||
@@ -28,8 +26,7 @@ public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedCo
|
||||
@Default
|
||||
private boolean zeroIndexed = false;
|
||||
|
||||
public StitchedImageTemplate(Loader files, ConfigPack pack) {
|
||||
this.files = files;
|
||||
public StitchedImageTemplate(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@@ -39,7 +36,7 @@ public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedCo
|
||||
for(int i = 0; i < rows; i++) {
|
||||
for(int j = 0; j < cols; j++) {
|
||||
try {
|
||||
grid[i][j] = ImageCache.load(getFormattedPath(i, j), pack, files);
|
||||
grid[i][j] = ImageCache.load(getFormattedPath(i, j), pack);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.addons.structure.mutator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.registry.key.Keyed;
|
||||
import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
@@ -9,8 +11,6 @@ import com.dfsek.terra.api.world.WritableWorld;
|
||||
import com.dfsek.terra.api.world.util.ReadInterceptor;
|
||||
import com.dfsek.terra.api.world.util.WriteInterceptor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class MutatedStructure implements Structure, Keyed<MutatedStructure> {
|
||||
private final RegistryKey key;
|
||||
|
||||
+16
-7
@@ -16,6 +16,7 @@ import net.querz.nbt.tag.Tag;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
@@ -29,7 +30,7 @@ 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.structure.Structure;
|
||||
import com.dfsek.terra.api.util.StringUtil;
|
||||
import com.dfsek.terra.api.util.FileUtil;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
|
||||
|
||||
@@ -58,13 +59,21 @@ public class SpongeSchematicAddon implements AddonInitializer {
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
|
||||
event.getPack()
|
||||
.getLoader()
|
||||
.open("", ".schem")
|
||||
.thenEntries(entries -> entries
|
||||
try {
|
||||
FileUtil.filesWithExtension(event.getPack().getRootPath(), ".schem")
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(entry -> convert(entry.getValue(), StringUtil.fileName(entry.getKey())))
|
||||
.forEach(structureRegistry::register)).close();
|
||||
.map(entry -> {
|
||||
try {
|
||||
return convert(Files.newInputStream(entry.getValue()), FileUtil.fileName(entry.getKey()));
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException("Failed to load config " + entry.getKey(), e);
|
||||
}
|
||||
})
|
||||
.forEach(structureRegistry::register);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException("Error occurred while reading config pack files", e);
|
||||
}
|
||||
})
|
||||
.failThrough();
|
||||
}
|
||||
|
||||
+26
-21
@@ -7,6 +7,9 @@
|
||||
|
||||
package com.dfsek.terra.addons.terrascript;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.addons.terrascript.parser.exceptions.ParseException;
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.functions.FunctionBuilder;
|
||||
@@ -19,7 +22,7 @@ import com.dfsek.terra.api.inject.annotations.Inject;
|
||||
import com.dfsek.terra.api.registry.CheckedRegistry;
|
||||
import com.dfsek.terra.api.structure.LootTable;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
import com.dfsek.terra.api.util.StringUtil;
|
||||
import com.dfsek.terra.api.util.FileUtil;
|
||||
|
||||
|
||||
public class TerraScriptAddon implements AddonInitializer {
|
||||
@@ -37,26 +40,28 @@ public class TerraScriptAddon implements AddonInitializer {
|
||||
.then(event -> {
|
||||
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
|
||||
CheckedRegistry<LootTable> lootRegistry = event.getPack().getOrCreateRegistry(LootTable.class);
|
||||
event.getPack().getLoader().open("", ".tesf").thenEntries(
|
||||
entries ->
|
||||
entries.stream()
|
||||
.parallel()
|
||||
.map(entry -> {
|
||||
try {
|
||||
String id = StringUtil.fileName(entry.getKey());
|
||||
return new StructureScript(entry.getValue(),
|
||||
addon.key(id),
|
||||
platform,
|
||||
structureRegistry,
|
||||
lootRegistry,
|
||||
event.getPack().getOrCreateRegistry(FunctionBuilder.class));
|
||||
} catch(ParseException e) {
|
||||
throw new RuntimeException("Failed to load script \"" + entry.getKey() + "\"", e);
|
||||
}
|
||||
})
|
||||
.toList()
|
||||
.forEach(structureRegistry::register))
|
||||
.close();
|
||||
try {
|
||||
FileUtil.filesWithExtension(event.getPack().getRootPath(), ".tesf")
|
||||
.entrySet()
|
||||
.stream()
|
||||
.parallel()
|
||||
.map(entry -> {
|
||||
try {
|
||||
String id = FileUtil.fileName(entry.getKey());
|
||||
return new StructureScript(Files.newInputStream(entry.getValue()),
|
||||
addon.key(id),
|
||||
platform,
|
||||
structureRegistry,
|
||||
lootRegistry,
|
||||
event.getPack().getOrCreateRegistry(FunctionBuilder.class));
|
||||
} catch(ParseException | IOException e) {
|
||||
throw new RuntimeException("Failed to load script \"" + entry.getKey() + "\"", e);
|
||||
}
|
||||
})
|
||||
.forEach(structureRegistry::register);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException("Error occurred while reading config pack files", e);
|
||||
}
|
||||
})
|
||||
.priority(100)
|
||||
.failThrough();
|
||||
|
||||
+2
-2
@@ -7,13 +7,13 @@
|
||||
|
||||
package com.dfsek.terra.addons.terrascript.script.builders;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.addons.terrascript.script.functions.CheckBlockFunction;
|
||||
import com.dfsek.terra.addons.terrascript.tokenizer.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class CheckBlockFunctionBuilder implements FunctionBuilder<CheckBlockFunction> {
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
+2
-2
@@ -10,8 +10,8 @@ package com.dfsek.terra.addons.terrascript.script.functions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
|
||||
@@ -32,7 +32,7 @@ public class BlockFunction implements Function<Void> {
|
||||
protected final Returnable<Number> x, y, z;
|
||||
protected final Returnable<String> blockData;
|
||||
protected final Platform platform;
|
||||
private final Map<String, BlockState> data = new ConcurrentHashMap<>();
|
||||
private final Map<String, BlockState> data = new HashMap<>();
|
||||
private final Returnable<Boolean> overwrite;
|
||||
private final Returnable<Boolean> physics;
|
||||
private final Position position;
|
||||
|
||||
@@ -2,10 +2,10 @@ dependencies {
|
||||
api("ca.solo-studios", "strata", Versions.Libraries.strata)
|
||||
compileOnlyApi("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
testImplementation("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
api("org.incendo", "cloud-core", Versions.Libraries.cloud)
|
||||
api("cloud.commandframework", "cloud-core", Versions.Libraries.cloud)
|
||||
|
||||
api("com.dfsek.tectonic", "common", Versions.Libraries.tectonic)
|
||||
|
||||
api("com.github.ben-manes.caffeine", "caffeine", Versions.Libraries.caffeine)
|
||||
api("com.github.ben-manes.caffeine:caffeine:3.1.0")
|
||||
|
||||
}
|
||||
@@ -81,7 +81,4 @@ public interface Platform extends LoaderRegistrar {
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
Profiler getProfiler();
|
||||
|
||||
@Contract(pure = true)
|
||||
int getGenerationThreads();
|
||||
}
|
||||
|
||||
+70
-50
@@ -1,19 +1,18 @@
|
||||
package com.dfsek.terra.api.command.arguments;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.incendo.cloud.component.CommandComponent;
|
||||
import org.incendo.cloud.component.DefaultValue;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ArgumentParseResult;
|
||||
import org.incendo.cloud.parser.ArgumentParser;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -23,22 +22,39 @@ import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
public class RegistryArgument {
|
||||
public class RegistryArgument<T, R> extends CommandArgument<T, R> {
|
||||
private RegistryArgument(
|
||||
boolean required,
|
||||
@NonNull String name,
|
||||
Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeToken<R> typeToken,
|
||||
@NonNull String defaultValue,
|
||||
@Nullable BiFunction<CommandContext<T>, String, List<String>> suggestionsProvider,
|
||||
@NonNull ArgumentDescription description
|
||||
) {
|
||||
super(required,
|
||||
name,
|
||||
new RegistryArgumentParser<>(registryFunction),
|
||||
defaultValue,
|
||||
typeToken,
|
||||
suggestionsProvider,
|
||||
description);
|
||||
}
|
||||
|
||||
public static <T, R> Builder<T, R> builder(String name, Registry<R> registry) {
|
||||
return new Builder<>(name, registry);
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> of(String name, Registry<R> registry) {
|
||||
public static <T, R> CommandArgument<T, R> of(String name, Registry<R> registry) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).build();
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> optional(String name, Registry<R> registry) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).optional().build();
|
||||
public static <T, R> CommandArgument<T, R> optional(String name, Registry<R> registry) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).asOptional().build();
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> optional(String name, Registry<R> registry, DefaultValue<T, R> defaultKey) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).optional(defaultKey).build();
|
||||
public static <T, R> CommandArgument<T, R> optional(String name, Registry<R> registry, String defaultKey) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).asOptionalWithDefault(defaultKey).build();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -47,36 +63,49 @@ public class RegistryArgument {
|
||||
return new Builder<>(name, registryFunction, (TypeToken<R>) TypeToken.get(registryType.getType()));
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> of(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType) {
|
||||
public static <T, R> CommandArgument<T, R> of(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType) {
|
||||
return RegistryArgument.<T, R>builder(name, registryFunction, registryType).build();
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> optional(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType) {
|
||||
return RegistryArgument.builder(name, registryFunction, registryType).optional().build();
|
||||
public static <T, R> CommandArgument<T, R> optional(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType) {
|
||||
return RegistryArgument.builder(name, registryFunction, registryType).asOptional().build();
|
||||
}
|
||||
|
||||
public static <T, R> CommandComponent<T> optional(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType, DefaultValue<T, R> defaultKey) {
|
||||
return RegistryArgument.builder(name, registryFunction, registryType).optional(defaultKey).build();
|
||||
public static <T, R> CommandArgument<T, R> optional(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType, String defaultKey) {
|
||||
return RegistryArgument.builder(name, registryFunction, registryType).asOptionalWithDefault(defaultKey).build();
|
||||
}
|
||||
|
||||
public static final class Builder<T, R> extends CommandComponent.Builder<T, R> {
|
||||
public static final class Builder<T, R> extends CommandArgument.Builder<T, R> {
|
||||
private final Function<CommandContext<T>, Registry<R>> registryFunction;
|
||||
private final TypeToken<R> typeToken;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Builder(@NonNull String name, Registry<R> registry) {
|
||||
super();
|
||||
this.name(name);
|
||||
this.parser(ParserDescriptor.of(
|
||||
new RegistryArgumentParser<>(commandContext -> registry),
|
||||
(TypeToken<R>) TypeToken.get(registry.getType().getType())));
|
||||
super((TypeToken<R>) TypeToken.get(registry.getType().getType()), name);
|
||||
this.registryFunction = commandContext -> registry;
|
||||
this.typeToken = (TypeToken<R>) TypeToken.get(registry.getType().getType());
|
||||
}
|
||||
|
||||
private Builder(@NonNull String name, Function<CommandContext<T>, Registry<R>> registryFunction, TypeToken<R> typeToken) {
|
||||
super();
|
||||
this.name(name);
|
||||
this.parser(ParserDescriptor.of(new RegistryArgumentParser<>(registryFunction), typeToken));
|
||||
super(typeToken, name);
|
||||
this.typeToken = typeToken;
|
||||
this.registryFunction = registryFunction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RegistryArgument<T, R> build() {
|
||||
return new RegistryArgument<>(
|
||||
isRequired(),
|
||||
getName(),
|
||||
registryFunction,
|
||||
typeToken,
|
||||
getDefaultValue(),
|
||||
getSuggestionsProvider(),
|
||||
getDefaultDescription()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,12 +119,12 @@ public class RegistryArgument {
|
||||
|
||||
@Override
|
||||
public @NonNull ArgumentParseResult<@NonNull R> parse(@NonNull CommandContext<@NonNull T> commandContext,
|
||||
@NonNull CommandInput commandInput) {
|
||||
String input = commandInput.readString();
|
||||
String next = commandInput.peekString();
|
||||
if(next.equals(":")) {
|
||||
input += commandInput.readString();
|
||||
input += commandInput.readString();
|
||||
@NonNull Queue<@NonNull String> inputQueue) {
|
||||
String input = inputQueue.remove();
|
||||
String next = inputQueue.peek();
|
||||
if(next != null && next.equals(":")) {
|
||||
input += inputQueue.remove();
|
||||
input += inputQueue.remove();
|
||||
}
|
||||
|
||||
Registry<R> registry = registryFunction.apply(commandContext);
|
||||
@@ -117,17 +146,8 @@ public class RegistryArgument {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull SuggestionProvider<T> suggestionProvider() {
|
||||
return new SuggestionProvider<>() {
|
||||
@Override
|
||||
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(
|
||||
@NonNull CommandContext<T> context, @NonNull CommandInput input) {
|
||||
|
||||
// TODO: Verify whether this is correct
|
||||
return CompletableFuture.completedFuture(registryFunction.apply(context).keys().stream().map(
|
||||
registryKey -> Suggestion.suggestion(registryKey.toString())).sorted().collect(Collectors.toList()));
|
||||
}
|
||||
};
|
||||
public @NonNull List<@NonNull String> suggestions(@NonNull CommandContext<T> commandContext, @NonNull String input) {
|
||||
return registryFunction.apply(commandContext).keys().stream().map(RegistryKey::toString).sorted().collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.dfsek.terra.api.config;
|
||||
import ca.solostudios.strata.version.Version;
|
||||
import ca.solostudios.strata.version.VersionRange;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -43,7 +44,7 @@ public interface ConfigPack extends LoaderRegistrar,
|
||||
|
||||
List<GenerationStage> getStages();
|
||||
|
||||
Loader getLoader();
|
||||
Path getRootPath();
|
||||
|
||||
String getAuthor();
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 Polyhedral Development
|
||||
*
|
||||
* The Terra API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the common/api directory.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.api.config;
|
||||
|
||||
import com.dfsek.tectonic.api.exception.ConfigException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
||||
public interface Loader {
|
||||
|
||||
Loader thenNames(Consumer<List<String>> consumer) throws ConfigException;
|
||||
|
||||
Loader thenEntries(Consumer<Set<Map.Entry<String, InputStream>>> consumer) throws ConfigException;
|
||||
|
||||
/**
|
||||
* Get a single file from this Loader.
|
||||
*
|
||||
* @param singleFile File to get
|
||||
*
|
||||
* @return InputStream from file.
|
||||
*/
|
||||
InputStream get(String singleFile) throws IOException;
|
||||
|
||||
/**
|
||||
* Open a subdirectory.
|
||||
*
|
||||
* @param directory Directory to open
|
||||
* @param extension File extension
|
||||
*/
|
||||
Loader open(String directory, String extension);
|
||||
|
||||
/**
|
||||
* Close all InputStreams opened.
|
||||
*/
|
||||
Loader close();
|
||||
}
|
||||
+1
-8
@@ -12,7 +12,6 @@ import com.dfsek.tectonic.api.config.Configuration;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
import com.dfsek.terra.api.event.events.FailThroughEvent;
|
||||
import com.dfsek.terra.api.event.events.PackEvent;
|
||||
|
||||
@@ -25,13 +24,11 @@ import com.dfsek.terra.api.event.events.PackEvent;
|
||||
*/
|
||||
public class ConfigurationDiscoveryEvent implements PackEvent, FailThroughEvent {
|
||||
private final ConfigPack pack;
|
||||
private final Loader loader;
|
||||
|
||||
private final BiConsumer<String, Configuration> consumer;
|
||||
|
||||
public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, BiConsumer<String, Configuration> consumer) {
|
||||
public ConfigurationDiscoveryEvent(ConfigPack pack, BiConsumer<String, Configuration> consumer) {
|
||||
this.pack = pack;
|
||||
this.loader = loader;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@@ -43,8 +40,4 @@ public class ConfigurationDiscoveryEvent implements PackEvent, FailThroughEvent
|
||||
public ConfigPack getPack() {
|
||||
return pack;
|
||||
}
|
||||
|
||||
public Loader getLoader() {
|
||||
return loader;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
package com.dfsek.terra.api.event.events.platform;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
|
||||
import com.dfsek.terra.api.command.CommandSender;
|
||||
import com.dfsek.terra.api.event.events.Event;
|
||||
|
||||
import org.incendo.cloud.CommandManager;
|
||||
|
||||
|
||||
public class CommandRegistrationEvent implements Event {
|
||||
private final CommandManager<CommandSender> commandManager;
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package com.dfsek.terra.api.noise;
|
||||
|
||||
/**
|
||||
* A NoiseSampler which additionally may provide a 1st directional derivative
|
||||
*/
|
||||
public interface DerivativeNoiseSampler extends NoiseSampler {
|
||||
|
||||
static boolean isDifferentiable(NoiseSampler sampler) {
|
||||
return sampler instanceof DerivativeNoiseSampler dSampler && dSampler.isDifferentiable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Samplers may or may not be able to provide a derivative depending on what
|
||||
* inputs they take, this method signals whether this is the case.
|
||||
*
|
||||
* @return If the noise sampler provides a derivative or not
|
||||
*/
|
||||
boolean isDifferentiable();
|
||||
|
||||
/**
|
||||
* Derivative return version of standard 2D noise evaluation
|
||||
*
|
||||
* @param seed
|
||||
* @param x
|
||||
* @param y
|
||||
*
|
||||
* @return 3 element array, in index order: noise value, partial x derivative, partial y derivative
|
||||
*/
|
||||
double[] noised(long seed, double x, double y);
|
||||
|
||||
/**
|
||||
* Derivative return version of standard 3D noise evaluation
|
||||
*
|
||||
* @param seed
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
*
|
||||
* @return 4 element array, in index order: noise value, partial x derivative, partial y derivative, partial z derivative
|
||||
*/
|
||||
double[] noised(long seed, double x, double y, double z);
|
||||
}
|
||||
@@ -7,12 +7,12 @@
|
||||
|
||||
package com.dfsek.terra.api.structure;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public interface Structure {
|
||||
boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.util.function.Function.identity;
|
||||
|
||||
|
||||
public class FileUtil {
|
||||
public static Map<String, Path> filesWithExtension(Path start, String... extensions) throws IOException {
|
||||
if(Files.notExists(start) || !Files.isDirectory(start)) return Collections.emptyMap();
|
||||
try(Stream<Path> paths = Files.walk(start)) {
|
||||
return paths
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(p -> Arrays.stream(extensions).anyMatch(e -> p.getFileName().toString().endsWith(e)))
|
||||
.collect(Collectors.toMap(p -> start.relativize(p).toString(), identity()));
|
||||
}
|
||||
}
|
||||
|
||||
public static String fileName(String path) {
|
||||
if(path.contains(File.separator)) {
|
||||
return path.substring(path.lastIndexOf(File.separatorChar) + 1, path.lastIndexOf('.'));
|
||||
} else if(path.contains("/")) {
|
||||
return path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf('.'));
|
||||
} else if(path.contains(".")) {
|
||||
return path.substring(0, path.lastIndexOf('.'));
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2023 Polyhedral Development
|
||||
*
|
||||
* The Terra API is licensed under the terms of the MIT License. For more details,
|
||||
* reference the LICENSE file in the common/api directory.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
||||
public class StringUtil {
|
||||
public static String fileName(String path) {
|
||||
if(path.contains(File.separator)) {
|
||||
return path.substring(path.lastIndexOf(File.separatorChar) + 1, path.lastIndexOf('.'));
|
||||
} else if(path.contains("/")) {
|
||||
return path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf('.'));
|
||||
} else if(path.contains(".")) {
|
||||
return path.substring(0, path.lastIndexOf('.'));
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@
|
||||
package com.dfsek.terra.api.util.reflection;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
@@ -27,18 +26,6 @@ import java.util.stream.Stream;
|
||||
|
||||
|
||||
public final class ReflectionUtil {
|
||||
private static final Unsafe UNSAFE;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
UNSAFE = (Unsafe) unsafeField.get(null);
|
||||
} catch(NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static Field[] getFields(@NotNull Class<?> type) {
|
||||
Field[] result = type.getDeclaredFields();
|
||||
Class<?> parentClass = type.getSuperclass();
|
||||
@@ -48,14 +35,6 @@ public final class ReflectionUtil {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void setFinalField(Object obj, String fieldName, Object value) throws NoSuchFieldException {
|
||||
Field field = obj.getClass().getDeclaredField(fieldName);
|
||||
field.setAccessible(true);
|
||||
long fieldOffset = UNSAFE.objectFieldOffset(field);
|
||||
|
||||
UNSAFE.putObject(obj, fieldOffset, value);
|
||||
}
|
||||
|
||||
public static Method[] getMethods(@NotNull Class<?> type) {
|
||||
Method[] result = type.getDeclaredMethods();
|
||||
Class<?> parentClass = type.getSuperclass();
|
||||
|
||||
+2
-4
@@ -7,8 +7,6 @@
|
||||
|
||||
package com.dfsek.terra.api.world.biome.generation;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
|
||||
import org.jetbrains.annotations.Contract;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -93,11 +91,11 @@ public interface BiomeProvider {
|
||||
return StreamSupport.stream(getBiomes().spliterator(), false);
|
||||
}
|
||||
|
||||
default CachingBiomeProvider caching(Platform platform) {
|
||||
default CachingBiomeProvider caching() {
|
||||
if(this instanceof CachingBiomeProvider cachingBiomeProvider) {
|
||||
return cachingBiomeProvider;
|
||||
}
|
||||
return new CachingBiomeProvider(this, platform.getGenerationThreads());
|
||||
return new CachingBiomeProvider(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+6
-7
@@ -21,20 +21,19 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
||||
private final LoadingCache<SeededVector3, Biome> cache;
|
||||
private final LoadingCache<SeededVector2, Optional<Biome>> baseCache;
|
||||
|
||||
protected CachingBiomeProvider(BiomeProvider delegate, int generationThreads) {
|
||||
protected CachingBiomeProvider(BiomeProvider delegate) {
|
||||
this.delegate = delegate;
|
||||
this.res = delegate.resolution();
|
||||
int size = generationThreads * 98304;
|
||||
this.cache = Caffeine
|
||||
.newBuilder()
|
||||
.scheduler(Scheduler.disabledScheduler())
|
||||
.initialCapacity(size)
|
||||
.maximumSize(size) // 1 full chunk (high res)
|
||||
.initialCapacity(98304)
|
||||
.maximumSize(98304) // 1 full chunk (high res)
|
||||
.build(vec -> delegate.getBiome(vec.x * res, vec.y * res, vec.z * res, vec.seed));
|
||||
|
||||
this.baseCache = Caffeine
|
||||
.newBuilder()
|
||||
.maximumSize(256L * generationThreads) // 1 full chunk (high res)
|
||||
.maximumSize(256) // 1 full chunk (high res)
|
||||
.build(vec -> delegate.getBaseBiome(vec.x * res, vec.z * res, vec.seed));
|
||||
|
||||
}
|
||||
@@ -78,7 +77,7 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
||||
int code = x;
|
||||
code = 31 * code + y;
|
||||
code = 31 * code + z;
|
||||
return 31 * code + (Long.hashCode(seed));
|
||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +95,7 @@ public class CachingBiomeProvider implements BiomeProvider, Handle {
|
||||
public int hashCode() {
|
||||
int code = x;
|
||||
code = 31 * code + z;
|
||||
return 31 * code + (Long.hashCode(seed));
|
||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import com.dfsek.tectonic.api.TypeRegistry;
|
||||
|
||||
import com.dfsek.terra.registry.master.ConfigRegistry.PackLoadFailuresException;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -147,18 +150,29 @@ public abstract class AbstractPlatform implements Platform {
|
||||
|
||||
eventManager.getHandler(FunctionalEventHandler.class)
|
||||
.register(internalAddon, PlatformInitializationEvent.class)
|
||||
.then(event -> {
|
||||
logger.info("Loading config packs...");
|
||||
configRegistry.loadAll(this);
|
||||
logger.info("Loaded packs.");
|
||||
})
|
||||
.then(event -> loadConfigPacks())
|
||||
.global();
|
||||
|
||||
|
||||
logger.info("Terra addons successfully loaded.");
|
||||
logger.info("Finished initialization.");
|
||||
}
|
||||
|
||||
protected boolean loadConfigPacks() {
|
||||
logger.info("Loading config packs...");
|
||||
ConfigRegistry configRegistry = getRawConfigRegistry();
|
||||
configRegistry.clear();
|
||||
try {
|
||||
configRegistry.loadAll(this);
|
||||
} catch(IOException e) {
|
||||
logger.error("Failed to load config packs", e);
|
||||
return false;
|
||||
} catch(PackLoadFailuresException e) {
|
||||
e.getExceptions().forEach(ex -> logger.error("Failed to load config pack", ex));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected InternalAddon loadAddons() {
|
||||
List<BaseAddon> addonList = new ArrayList<>();
|
||||
|
||||
@@ -310,24 +324,6 @@ public abstract class AbstractPlatform implements Platform {
|
||||
}
|
||||
}
|
||||
|
||||
public static int getGenerationThreadsWithReflection(String className, String fieldName, String project) {
|
||||
try {
|
||||
Class aClass = Class.forName(className);
|
||||
int threads = aClass.getField(fieldName).getInt(null);
|
||||
logger.info("{} found, setting {} generation threads.", project, threads);
|
||||
return threads;
|
||||
} catch(ClassNotFoundException e) {
|
||||
logger.info("{} not found.", project);
|
||||
} catch(NoSuchFieldException e) {
|
||||
logger.warn("{} found, but {} field not found this probably means {0} has changed its code and " +
|
||||
"Terra has not updated to reflect that.", project, fieldName);
|
||||
} catch(IllegalAccessException e) {
|
||||
logger.error("Failed to access {} field in {}, assuming 1 generation thread.", fieldName, project, e);
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
loaders.register(registry);
|
||||
@@ -357,9 +353,4 @@ public abstract class AbstractPlatform implements Platform {
|
||||
public @NotNull Profiler getProfiler() {
|
||||
return profiler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGenerationThreads() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
-66
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* This file is part of Terra.
|
||||
*
|
||||
* Terra is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Terra is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.config.fileloaders;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
/**
|
||||
* Load all {@code *.yml} files from a {@link java.nio.file.Path}.
|
||||
*/
|
||||
public class FolderLoader extends LoaderImpl {
|
||||
private static final Logger logger = LoggerFactory.getLogger(FolderLoader.class);
|
||||
|
||||
private final Path path;
|
||||
|
||||
public FolderLoader(Path path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
return new FileInputStream(new File(path.toFile(), singleFile));
|
||||
}
|
||||
|
||||
protected void load(String directory, String extension) {
|
||||
File newPath = new File(path.toFile(), directory);
|
||||
newPath.mkdirs();
|
||||
try(Stream<Path> paths = Files.walk(newPath.toPath())) {
|
||||
paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(extension)).forEach(file -> {
|
||||
try {
|
||||
String rel = newPath.toPath().relativize(file).toString();
|
||||
streams.put(rel, new FileInputStream(file.toFile()));
|
||||
} catch(FileNotFoundException e) {
|
||||
logger.error("Could not find file to load", e);
|
||||
}
|
||||
});
|
||||
} catch(IOException e) {
|
||||
logger.error("Error while loading files", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
-83
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* This file is part of Terra.
|
||||
*
|
||||
* Terra is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Terra is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.config.fileloaders;
|
||||
|
||||
import com.dfsek.tectonic.api.exception.ConfigException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
|
||||
|
||||
public abstract class LoaderImpl implements Loader {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LoaderImpl.class);
|
||||
|
||||
protected final Map<String, InputStream> streams = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Loader thenNames(Consumer<List<String>> consumer) throws ConfigException {
|
||||
consumer.accept(new ArrayList<>(streams.keySet()));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader thenEntries(Consumer<Set<Map.Entry<String, InputStream>>> consumer) throws ConfigException {
|
||||
consumer.accept(streams.entrySet());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a subdirectory.
|
||||
*
|
||||
* @param directory Directory to open
|
||||
* @param extension File extension
|
||||
*/
|
||||
@Override
|
||||
public LoaderImpl open(String directory, String extension) {
|
||||
if(!streams.isEmpty()) throw new IllegalStateException("Attempted to load new directory before closing existing InputStreams");
|
||||
load(directory, extension);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all InputStreams opened.
|
||||
*/
|
||||
@Override
|
||||
public Loader close() {
|
||||
streams.forEach((name, input) -> {
|
||||
try {
|
||||
input.close();
|
||||
} catch(IOException e) {
|
||||
logger.error("Error occurred while loading", e);
|
||||
}
|
||||
});
|
||||
streams.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
protected abstract void load(String directory, String extension);
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* This file is part of Terra.
|
||||
*
|
||||
* Terra is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Terra is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Terra. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.dfsek.terra.config.fileloaders;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
|
||||
public class ZIPLoader extends LoaderImpl {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ZIPLoader.class);
|
||||
|
||||
private final ZipFile file;
|
||||
|
||||
public ZIPLoader(ZipFile file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream get(String singleFile) throws IOException {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(!entry.isDirectory() && entry.getName().equals(singleFile)) return file.getInputStream(entry);
|
||||
}
|
||||
throw new IllegalArgumentException("No such file: " + singleFile);
|
||||
}
|
||||
|
||||
protected void load(String directory, String extension) {
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) {
|
||||
try {
|
||||
String rel = entry.getName().substring(directory.length());
|
||||
streams.put(rel, file.getInputStream(entry));
|
||||
} catch(IOException e) {
|
||||
logger.error("Error while loading file from zip", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-5
@@ -27,10 +27,10 @@ import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.nio.file.Files;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
|
||||
|
||||
@@ -39,12 +39,10 @@ import com.dfsek.terra.api.properties.Properties;
|
||||
*/
|
||||
@Deprecated
|
||||
public class BufferedImageLoader implements TypeLoader<BufferedImage> {
|
||||
private final Loader files;
|
||||
|
||||
private final ConfigPack pack;
|
||||
|
||||
public BufferedImageLoader(Loader files, ConfigPack pack) {
|
||||
this.files = files;
|
||||
public BufferedImageLoader(ConfigPack pack) {
|
||||
this.pack = pack;
|
||||
if(!pack.getContext().has(ImageCache.class))
|
||||
pack.getContext().put(new ImageCache(new ConcurrentHashMap<>()));
|
||||
@@ -55,7 +53,7 @@ public class BufferedImageLoader implements TypeLoader<BufferedImage> {
|
||||
throws LoadException {
|
||||
return pack.getContext().get(ImageCache.class).map.computeIfAbsent((String) c, s -> {
|
||||
try {
|
||||
return ImageIO.read(files.get(s));
|
||||
return ImageIO.read(Files.newInputStream(pack.getRootPath().resolve(s)));
|
||||
} catch(IOException e) {
|
||||
throw new LoadException("Unable to load image", e, depthTracker);
|
||||
}
|
||||
|
||||
+32
-52
@@ -33,15 +33,15 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -51,15 +51,12 @@ import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.api.config.ConfigFactory;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.ConfigType;
|
||||
import com.dfsek.terra.api.config.Loader;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationDiscoveryEvent;
|
||||
import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent;
|
||||
@@ -72,15 +69,12 @@ import com.dfsek.terra.api.registry.OpenRegistry;
|
||||
import com.dfsek.terra.api.registry.Registry;
|
||||
import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||
import com.dfsek.terra.api.tectonic.ShortcutLoader;
|
||||
import com.dfsek.terra.api.util.generic.Construct;
|
||||
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||
import com.dfsek.terra.api.util.reflection.ReflectionUtil;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
import com.dfsek.terra.api.world.chunk.generation.stage.GenerationStage;
|
||||
import com.dfsek.terra.api.world.chunk.generation.util.provider.ChunkGeneratorProvider;
|
||||
import com.dfsek.terra.config.fileloaders.FolderLoader;
|
||||
import com.dfsek.terra.config.fileloaders.ZIPLoader;
|
||||
import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader;
|
||||
import com.dfsek.terra.config.loaders.config.BufferedImageLoader;
|
||||
import com.dfsek.terra.config.preprocessor.MetaListLikePreprocessor;
|
||||
@@ -107,7 +101,7 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
private final AbstractConfigLoader abstractConfigLoader = new AbstractConfigLoader();
|
||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||
private final Platform platform;
|
||||
private final Loader loader;
|
||||
private final Path rootPath;
|
||||
|
||||
private final Map<BaseAddon, VersionRange> addons;
|
||||
|
||||
@@ -121,40 +115,29 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
|
||||
private final RegistryKey key;
|
||||
|
||||
public ConfigPackImpl(File folder, Platform platform) {
|
||||
this(new FolderLoader(folder.toPath()), Construct.construct(() -> {
|
||||
try {
|
||||
return new YamlConfiguration(new FileInputStream(new File(folder, "pack.yml")), "pack.yml");
|
||||
} catch(FileNotFoundException e) {
|
||||
throw new UncheckedIOException("No pack.yml file found in " + folder.getAbsolutePath(), e);
|
||||
}
|
||||
}), platform);
|
||||
}
|
||||
|
||||
public ConfigPackImpl(ZipFile file, Platform platform) {
|
||||
this(new ZIPLoader(file), Construct.construct(() -> {
|
||||
ZipEntry pack = null;
|
||||
Enumeration<? extends ZipEntry> entries = file.entries();
|
||||
while(entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if(entry.getName().equals("pack.yml")) pack = entry;
|
||||
}
|
||||
|
||||
if(pack == null) throw new IllegalArgumentException("No pack.yml file found in " + file.getName());
|
||||
|
||||
try {
|
||||
return new YamlConfiguration(file.getInputStream(pack), "pack.yml");
|
||||
} catch(IOException e) {
|
||||
throw new UncheckedIOException("Unable to load pack.yml from ZIP file", e);
|
||||
}
|
||||
}), platform);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private ConfigPackImpl(Loader loader, Configuration packManifest, Platform platform) {
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
public ConfigPackImpl(Path path, Platform platform) throws IOException {
|
||||
long start = System.nanoTime();
|
||||
|
||||
this.loader = loader;
|
||||
if(Files.notExists(path)) throw new FileNotFoundException("Could not load config pack, " + path + " does not exist");
|
||||
|
||||
if(Files.isDirectory(path)) {
|
||||
this.rootPath = path;
|
||||
} else if(Files.isRegularFile(path)) {
|
||||
if(!path.getFileName().toString().endsWith(".zip")) {
|
||||
throw new IOException("Could not load config pack, file " + path + " is not a zip");
|
||||
}
|
||||
FileSystem zipfs = FileSystems.newFileSystem(path);
|
||||
this.rootPath = zipfs.getPath("/");
|
||||
} else {
|
||||
throw new IOException("Could not load config pack from " + path);
|
||||
}
|
||||
|
||||
Path packManifestPath = rootPath.resolve("pack.yml");
|
||||
if(Files.notExists(packManifestPath)) throw new IOException("No pack.yml found in " + path);
|
||||
Configuration packManifest = new YamlConfiguration(Files.newInputStream(packManifestPath),
|
||||
packManifestPath.getFileName().toString());
|
||||
|
||||
this.platform = platform;
|
||||
this.configTypeRegistry = createConfigRegistry();
|
||||
|
||||
@@ -232,13 +215,13 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
ConfigPackPostTemplate packPostTemplate = new ConfigPackPostTemplate();
|
||||
selfLoader.load(packPostTemplate, packManifest);
|
||||
seededBiomeProvider =
|
||||
template.getBiomeCache() ? packPostTemplate.getProviderBuilder().caching(platform) : packPostTemplate.getProviderBuilder();
|
||||
template.getBiomeCache() ? packPostTemplate.getProviderBuilder().caching() : packPostTemplate.getProviderBuilder();
|
||||
checkDeadEntries();
|
||||
}
|
||||
|
||||
private Map<String, Configuration> discoverConfigurations() {
|
||||
Map<String, Configuration> configurations = new HashMap<>();
|
||||
platform.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader,
|
||||
platform.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this,
|
||||
(s, c) -> configurations.put(s.replace("\\", "/"),
|
||||
c))); // Create all the configs.
|
||||
return configurations;
|
||||
@@ -283,7 +266,7 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
@Override
|
||||
public void register(TypeRegistry registry) {
|
||||
registry.registerLoader(ConfigType.class, configTypeRegistry)
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(loader, this));
|
||||
.registerLoader(BufferedImage.class, new BufferedImageLoader(this));
|
||||
registryMap.forEach(registry::registerLoader);
|
||||
shortcuts.forEach(registry::registerLoader); // overwrite with delegated shortcuts if present
|
||||
}
|
||||
@@ -309,7 +292,6 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
return seededBiomeProvider;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getOrCreateRegistry(TypeKey<T> typeKey) {
|
||||
return (CheckedRegistry<T>) registryMap.computeIfAbsent(typeKey.getType(), c -> {
|
||||
@@ -348,8 +330,8 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader getLoader() {
|
||||
return loader;
|
||||
public Path getRootPath() {
|
||||
return rootPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -362,7 +344,7 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
return template.getVersion();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked,rawtypes")
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
public <T> ConfigPack registerShortcut(TypeKey<T> clazz, String shortcut, ShortcutLoader<T> loader) {
|
||||
ShortcutHolder<?> holder = shortcuts
|
||||
@@ -406,12 +388,10 @@ public class ConfigPackImpl implements ConfigPack {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> CheckedRegistry<T> getRegistry(Type type) {
|
||||
return (CheckedRegistry<T>) registryMap.get(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> CheckedRegistry<T> getCheckedRegistry(Type type) throws IllegalStateException {
|
||||
return (CheckedRegistry<T>) registryMap.get(type);
|
||||
|
||||
+3
-4
@@ -24,15 +24,14 @@ 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.preprocessor.Result;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.AnnotatedType;
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
public class MetaNumberPreprocessor extends MetaPreprocessor<Meta> {
|
||||
public static final TypeKey<String> META_STRING_KEY = new TypeKey<@Meta String>() {
|
||||
|
||||
+35
-38
@@ -17,14 +17,13 @@
|
||||
|
||||
package com.dfsek.terra.registry.master;
|
||||
|
||||
import com.dfsek.tectonic.api.exception.ConfigException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.io.Serial;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
@@ -37,44 +36,42 @@ import com.dfsek.terra.registry.OpenRegistryImpl;
|
||||
* Class to hold config packs
|
||||
*/
|
||||
public class ConfigRegistry extends OpenRegistryImpl<ConfigPack> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigRegistry.class);
|
||||
|
||||
public ConfigRegistry() {
|
||||
super(TypeKey.of(ConfigPack.class));
|
||||
}
|
||||
|
||||
public void load(File folder, Platform platform) throws ConfigException {
|
||||
ConfigPack pack = new ConfigPackImpl(folder, platform);
|
||||
registerChecked(pack.getRegistryKey(), pack);
|
||||
public void loadAll(Platform platform) throws IOException, PackLoadFailuresException {
|
||||
Path packsDirectory = platform.getDataFolder().toPath().resolve("packs");
|
||||
Files.createDirectories(packsDirectory);
|
||||
List<IOException> failedLoads = new ArrayList<>();
|
||||
try(Stream<Path> packs = Files.list(packsDirectory)) {
|
||||
packs.forEach(path -> {
|
||||
try {
|
||||
ConfigPack pack = new ConfigPackImpl(path, platform);
|
||||
registerChecked(pack.getRegistryKey(), pack);
|
||||
} catch(IOException e) {
|
||||
failedLoads.add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(!failedLoads.isEmpty()) {
|
||||
throw new PackLoadFailuresException(failedLoads);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean loadAll(Platform platform) {
|
||||
boolean valid = true;
|
||||
File packsFolder = new File(platform.getDataFolder(), "packs");
|
||||
packsFolder.mkdirs();
|
||||
for(File dir : Objects.requireNonNull(packsFolder.listFiles(File::isDirectory))) {
|
||||
try {
|
||||
load(dir, platform);
|
||||
} catch(ConfigException e) {
|
||||
logger.error("Error loading config pack {}", dir.getName(), e);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
for(File zip : Objects.requireNonNull(
|
||||
packsFolder.listFiles(file -> file.getName().endsWith(".zip") || file.getName().endsWith(".terra")))) {
|
||||
try {
|
||||
logger.info("Loading ZIP archive: {}", zip.getName());
|
||||
load(new ZipFile(zip), platform);
|
||||
} catch(IOException | ConfigException e) {
|
||||
logger.error("Error loading config pack {}", zip.getName(), e);
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
public static class PackLoadFailuresException extends Exception {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 538998844645186306L;
|
||||
|
||||
public void load(ZipFile file, Platform platform) throws ConfigException {
|
||||
ConfigPackImpl pack = new ConfigPackImpl(file, platform);
|
||||
registerChecked(pack.getRegistryKey(), pack);
|
||||
private final List<Throwable> exceptions;
|
||||
|
||||
public PackLoadFailuresException(List<? extends Throwable> exceptions) {
|
||||
this.exceptions = (List<Throwable>) exceptions;
|
||||
}
|
||||
|
||||
public List<Throwable> getExceptions() {
|
||||
return exceptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -1,7 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionSha256Sum=1541fa36599e12857140465f3c91a97409b4512501c26f9631fb113e392c5bd1
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user