mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-05-20 08:40:26 +00:00
Compare commits
89 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7ca61f82b2 | |||
| 6851999926 | |||
| 305255511d | |||
| 819be16d83 | |||
| 8a028b193a | |||
| d31679e6be | |||
| 9d328b12b3 | |||
| a743e9c015 | |||
| 43d52e4bc1 | |||
| accc07fa07 | |||
| c1d3155ddd | |||
| 9a01a6c6a0 | |||
| 1ae0d1f867 | |||
| 370b2e0122 | |||
| 331075e54d | |||
| 973590f5fd | |||
| 1a5ab6b505 | |||
| 14732328cd | |||
| 6c7974c302 | |||
| 1204b7a8c1 | |||
| fbe1c76e26 | |||
| add7803e65 | |||
| 4393a16b2f | |||
| b4fa635455 | |||
| 9f425c6159 | |||
| 158ffba2a5 | |||
| b7326c0ff6 | |||
| f70a83aec3 | |||
| 589cf83c38 | |||
| c374c2d5ef | |||
| 13782bb51e | |||
| 1aa3ef813c | |||
| 6cc53beecb | |||
| 2c45ba91aa | |||
| 6244ffca63 | |||
| 59d943b3ea | |||
| f605ee1937 | |||
| f87b7c07d9 | |||
| f1124aae6b | |||
| 9c8298fe53 | |||
| d69b0dba90 | |||
| 42166d5239 | |||
| d6772f51ea | |||
| f469193909 | |||
| 10d723372d | |||
| 1d05f95f74 | |||
| bd73427072 | |||
| 017b4608bc | |||
| 5f340f8ffd | |||
| 5b35eb041b | |||
| 699d5d1d62 | |||
| 07e3d0058d | |||
| b1ad820e1c | |||
| 3644ee7fca | |||
| b14b355c6f | |||
| 06457bf3ce | |||
| b63f5f4a8f | |||
| 8cf766e77b | |||
| a23d624ab9 | |||
| 15a298304e | |||
| 664d1a3191 | |||
| 73047284c8 | |||
| 3bef7d8572 | |||
| 08df5fc278 | |||
| 922cd35e84 | |||
| 44d23573b3 | |||
| e7cc275340 | |||
| fddc9a52b9 | |||
| 0758e13bc7 | |||
| d810cad8d0 | |||
| 4e7de501c0 | |||
| 9e60db4b0d | |||
| 4536767794 | |||
| 3fa4b21247 | |||
| 17acde09a3 | |||
| dd272bce64 | |||
| c20b1eaf10 | |||
| 72f761678a | |||
| 62317a2f3f | |||
| 823afd592b | |||
| ff03b38b81 | |||
| 35246d65b9 | |||
| 41652d29df | |||
| 142d364682 | |||
| 01e011a9ed | |||
| 94949c9120 | |||
| c52ad56ccc | |||
| f3476c5cc8 | |||
| 9c181f7ee1 |
@@ -18,10 +18,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
- name: Set up JDK 17
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93
|
||||
with:
|
||||
java-version: '17'
|
||||
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
|
||||
|
||||
+5
-4
@@ -1,8 +1,8 @@
|
||||
preRelease(true)
|
||||
|
||||
versionProjects(":common:api", version("6.5.0"))
|
||||
versionProjects(":common:implementation", version("6.5.0"))
|
||||
versionProjects(":platforms", version("6.5.0"))
|
||||
versionProjects(":common:api", version("6.6.0"))
|
||||
versionProjects(":common:implementation", version("6.6.0"))
|
||||
versionProjects(":platforms", version("6.6.0"))
|
||||
|
||||
|
||||
allprojects {
|
||||
@@ -15,6 +15,7 @@ allprojects {
|
||||
tasks.withType<JavaCompile>().configureEach {
|
||||
options.isFork = true
|
||||
options.isIncremental = true
|
||||
options.release.set(21)
|
||||
}
|
||||
|
||||
tasks.withType<Test>().configureEach {
|
||||
@@ -44,7 +45,7 @@ afterEvaluate {
|
||||
}
|
||||
project(":platforms:bukkit:common").configureDistribution()
|
||||
forSubProjects(":common:addons") {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
|
||||
tasks.named("build") {
|
||||
finalizedBy(tasks.named("shadowJar"))
|
||||
|
||||
@@ -9,18 +9,18 @@ repositories {
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
maven("https://repo.papermc.io/repository/maven-public/") {
|
||||
name = "PaperMC"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//TODO Allow pulling from Versions.kt
|
||||
implementation("com.github.johnrengelman", "shadow", "8.1.1")
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.5.11")
|
||||
implementation("com.gradleup.shadow", "shadow-gradle-plugin", "8.3.1")
|
||||
implementation("io.papermc.paperweight.userdev", "io.papermc.paperweight.userdev.gradle.plugin", "1.7.2")
|
||||
|
||||
implementation("org.ow2.asm", "asm", "9.6")
|
||||
implementation("org.ow2.asm", "asm-tree", "9.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.2")
|
||||
implementation("org.yaml", "snakeyaml", "2.3")
|
||||
}
|
||||
@@ -22,8 +22,8 @@ fun Project.configureCompilation() {
|
||||
apply<TectonicDocPlugin>()
|
||||
|
||||
configure<JavaPluginExtension> {
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_21
|
||||
targetCompatibility = JavaVersion.VERSION_21
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
|
||||
@@ -36,7 +36,7 @@ fun Project.configureDependencies() {
|
||||
maven("https://repo.codemc.org/repository/maven-public") {
|
||||
name = "CodeMC"
|
||||
}
|
||||
maven("https://papermc.io/repo/repository/maven-public/") {
|
||||
maven("https://repo.papermc.io/repository/maven-public/") {
|
||||
name = "PaperMC"
|
||||
}
|
||||
maven("https://files.minecraftforge.net/maven/") {
|
||||
@@ -48,6 +48,9 @@ fun Project.configureDependencies() {
|
||||
maven("https://jitpack.io") {
|
||||
name = "JitPack"
|
||||
}
|
||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/") {
|
||||
name = "Sonatype Snapshots"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -21,7 +21,7 @@ import kotlin.io.path.exists
|
||||
|
||||
|
||||
fun Project.configureDistribution() {
|
||||
apply(plugin = "com.github.johnrengelman.shadow")
|
||||
apply(plugin = "com.gradleup.shadow")
|
||||
|
||||
val downloadDefaultPacks = tasks.create("downloadDefaultPacks") {
|
||||
group = "terra"
|
||||
|
||||
@@ -8,27 +8,28 @@ object Versions {
|
||||
const val paralithic = "0.7.1"
|
||||
const val strata = "1.3.2"
|
||||
|
||||
const val cloud = "1.8.4"
|
||||
const val cloud = "2.0.0"
|
||||
const val cloudPaper = "2.0.0-beta.10"
|
||||
const val cloudFabric = "2.0.0-beta.9"
|
||||
|
||||
const val 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.1.1"
|
||||
const val apacheText = "1.11.0"
|
||||
const val apacheIO = "2.15.1"
|
||||
const val guava = "32.1.3-jre"
|
||||
const val asm = "9.6"
|
||||
const val snakeYml = "2.2"
|
||||
const val shadow = "8.3.1"
|
||||
const val apacheText = "1.12.0"
|
||||
const val apacheIO = "2.16.1"
|
||||
const val guava = "33.3.0-jre"
|
||||
const val asm = "9.7"
|
||||
const val snakeYml = "2.3"
|
||||
const val jetBrainsAnnotations = "24.1.0"
|
||||
const val junit = "5.10.1"
|
||||
const val junit = "5.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
object Fabric {
|
||||
const val fabricAPI = "0.91.2+${Mod.minecraft}"
|
||||
const val fabricAPI = "0.104.0+${Mod.minecraft}"
|
||||
}
|
||||
//
|
||||
// object Quilt {
|
||||
@@ -37,14 +38,14 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Mod {
|
||||
const val mixin = "0.12.5+mixin.0.8.5"
|
||||
const val mixin = "0.15.3+mixin.0.8.7"
|
||||
|
||||
const val minecraft = "1.20.4"
|
||||
const val yarn = "$minecraft+build.1"
|
||||
const val fabricLoader = "0.15.1"
|
||||
const val minecraft = "1.21.1"
|
||||
const val yarn = "$minecraft+build.3"
|
||||
const val fabricLoader = "0.16.5"
|
||||
|
||||
const val architecuryLoom = "1.4.369"
|
||||
const val architecturyPlugin = "3.4.151"
|
||||
const val architecuryLoom = "1.7.413"
|
||||
const val architecturyPlugin = "3.4.159"
|
||||
}
|
||||
//
|
||||
// object Forge {
|
||||
@@ -53,14 +54,14 @@ object Versions {
|
||||
// }
|
||||
|
||||
object Bukkit {
|
||||
const val minecraft = "1.20.4"
|
||||
const val paperBuild = "$minecraft-R0.1-20231209.173338-2"
|
||||
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.0"
|
||||
const val reflectionRemapper = "0.1.1"
|
||||
const val paperDevBundle = paperBuild
|
||||
const val runPaper = "2.2.2"
|
||||
const val paperWeight = "1.5.11"
|
||||
const val runPaper = "2.3.1"
|
||||
const val paperWeight = "1.7.2"
|
||||
}
|
||||
|
||||
//
|
||||
@@ -72,6 +73,7 @@ object Versions {
|
||||
//
|
||||
object CLI {
|
||||
const val nbt = "6.1"
|
||||
const val logback = "1.4.14"
|
||||
const val logback = "1.5.8"
|
||||
const val picocli = "4.7.6"
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.api;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
public interface Extrusion {
|
||||
Biome extrude(Biome original, int x, int y, int z, long seed);
|
||||
|
||||
+4
-3
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2;
|
||||
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
@@ -11,7 +13,6 @@ import java.util.stream.StreamSupport;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
@@ -23,7 +24,7 @@ import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
public class PipelineBiomeProvider implements BiomeProvider {
|
||||
|
||||
private final LoadingCache<SeededVector, BiomeChunk> biomeChunkCache;
|
||||
private final LoadingCache<SeededVector2Key, BiomeChunk> biomeChunkCache;
|
||||
private final int chunkSize;
|
||||
private final int resolution;
|
||||
private final NoiseSampler mutator;
|
||||
@@ -90,7 +91,7 @@ public class PipelineBiomeProvider implements BiomeProvider {
|
||||
int xInChunk = x - chunkWorldX;
|
||||
int zInChunk = z - chunkWorldZ;
|
||||
|
||||
return biomeChunkCache.get(new SeededVector(seed, chunkWorldX, chunkWorldZ)).get(xInChunk, zInChunk).getBiome();
|
||||
return biomeChunkCache.get(new SeededVector2Key(chunkWorldX, chunkWorldZ, seed)).get(xInChunk, zInChunk).getBiome();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+3
-1
@@ -1,10 +1,12 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface Pipeline {
|
||||
BiomeChunk generateChunk(SeededVector worldCoordinates);
|
||||
BiomeChunk generateChunk(SeededVector2Key worldCoordinates);
|
||||
|
||||
int getChunkSize();
|
||||
|
||||
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api;
|
||||
|
||||
public record SeededVector(long seed, int x, int z) {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof SeededVector that) {
|
||||
return this.z == that.z && this.x == that.x && this.seed == that.seed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int code = x;
|
||||
code = 31 * code + z;
|
||||
return 31 * code + ((int) (seed ^ (seed >>> 32)));
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.api.biome;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
|
||||
public final class DelegatedPipelineBiome implements PipelineBiome {
|
||||
private final Biome biome;
|
||||
|
||||
+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;
|
||||
|
||||
+8
-8
@@ -4,20 +4,20 @@ import java.util.List;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
|
||||
|
||||
public class BiomeChunkImpl implements BiomeChunk {
|
||||
|
||||
private final SeededVector worldOrigin;
|
||||
private final SeededVector2Key worldOrigin;
|
||||
private final int chunkOriginArrayIndex;
|
||||
private final int worldCoordinateScale;
|
||||
private final int size;
|
||||
private PipelineBiome[] biomes;
|
||||
|
||||
public BiomeChunkImpl(SeededVector worldOrigin, PipelineImpl pipeline) {
|
||||
public BiomeChunkImpl(SeededVector2Key worldOrigin, PipelineImpl pipeline) {
|
||||
|
||||
this.worldOrigin = worldOrigin;
|
||||
this.chunkOriginArrayIndex = pipeline.getChunkOriginArrayIndex();
|
||||
@@ -44,7 +44,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
for(int gridZ = 0; gridZ < gridSize; gridZ++) {
|
||||
int xIndex = gridOrigin + gridX * gridInterval;
|
||||
int zIndex = gridOrigin + gridZ * gridInterval;
|
||||
biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed(), xIndexToWorldCoordinate(xIndex),
|
||||
biomes[(xIndex * size) + zIndex] = pipeline.getSource().get(worldOrigin.seed, xIndexToWorldCoordinate(xIndex),
|
||||
zIndexToWorldCoordinate(zIndex));
|
||||
}
|
||||
}
|
||||
@@ -139,14 +139,14 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
}
|
||||
|
||||
private int xIndexToWorldCoordinate(int xIndex) {
|
||||
return (worldOrigin.x() + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
return (worldOrigin.x + xIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
}
|
||||
|
||||
private int zIndexToWorldCoordinate(int zIndex) {
|
||||
return (worldOrigin.z() + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
return (worldOrigin.z + zIndex - chunkOriginArrayIndex) * worldCoordinateScale;
|
||||
}
|
||||
|
||||
private SeededVector getOrigin() {
|
||||
private SeededVector2Key getOrigin() {
|
||||
return worldOrigin;
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ public class BiomeChunkImpl implements BiomeChunk {
|
||||
}
|
||||
|
||||
public long worldSeed() {
|
||||
return chunk.getOrigin().seed();
|
||||
return chunk.getOrigin().seed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,7 @@
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.pipeline;
|
||||
|
||||
import com.dfsek.terra.api.util.cache.SeededVector2Key;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -8,7 +10,6 @@ import java.util.List;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.BiomeChunk;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Expander;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Pipeline;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.SeededVector;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Source;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
|
||||
@@ -55,7 +56,7 @@ public class PipelineImpl implements Pipeline {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeChunk generateChunk(SeededVector worldCoordinates) {
|
||||
public BiomeChunk generateChunk(SeededVector2Key worldCoordinates) {
|
||||
return new BiomeChunkImpl(worldCoordinates, this);
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -7,17 +7,17 @@
|
||||
|
||||
package com.dfsek.terra.addons.biome.pipeline.v2.stage.mutators;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.Stage;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.api.biome.PipelineBiome;
|
||||
import com.dfsek.terra.addons.biome.pipeline.v2.pipeline.BiomeChunkImpl;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
|
||||
public class ReplaceListStage implements Stage {
|
||||
private final Map<PipelineBiome, ProbabilityCollection<PipelineBiome>> replace;
|
||||
|
||||
+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;
|
||||
|
||||
+2
-1
@@ -58,7 +58,8 @@ public class NoiseChunkGenerator3DAddon implements AddonInitializer {
|
||||
pack -> new NoiseChunkGenerator3D(pack, platform, config.getElevationBlend(),
|
||||
config.getHorizontalRes(),
|
||||
config.getVerticalRes(), noisePropertiesPropertyKey,
|
||||
paletteInfoPropertyKey, config.getSlantCalculationMethod()));
|
||||
paletteInfoPropertyKey, config.getSlantCalculationMethod(),
|
||||
config.isSlantPalettesEnabled()));
|
||||
event.getPack()
|
||||
.applyLoader(SlantHolder.Layer.class, SlantLayerTemplate::new);
|
||||
})
|
||||
|
||||
+8
@@ -26,6 +26,10 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Pr
|
||||
@Default
|
||||
private @Meta SlantCalculationMethod slantCalculationMethod = SlantCalculationMethod.Derivative;
|
||||
|
||||
@Value("slant.disable-palettes")
|
||||
@Default
|
||||
private @Meta boolean disableSlantPalettes = false;
|
||||
|
||||
public int getElevationBlend() {
|
||||
return elevationBlend;
|
||||
}
|
||||
@@ -41,4 +45,8 @@ public class NoiseChunkGeneratorPackConfigTemplate implements ConfigTemplate, Pr
|
||||
public SlantCalculationMethod getSlantCalculationMethod() {
|
||||
return slantCalculationMethod;
|
||||
}
|
||||
|
||||
public boolean isSlantPalettesEnabled() {
|
||||
return !disableSlantPalettes;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -8,17 +8,15 @@
|
||||
package com.dfsek.terra.addons.chunkgenerator.generation;
|
||||
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.palette.slant.SlantHolder;
|
||||
|
||||
import com.dfsek.terra.addons.chunkgenerator.generation.math.SlantCalculationMethod;
|
||||
|
||||
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.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;
|
||||
@@ -47,10 +45,13 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
|
||||
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) {
|
||||
PropertyKey<BiomePaletteInfo> paletteInfoPropertyKey,
|
||||
SlantCalculationMethod slantCalculationMethod, boolean useSlantPalettes) {
|
||||
this.platform = platform;
|
||||
this.air = platform.getWorldHandle().air();
|
||||
this.carverHorizontalResolution = carverHorizontalResolution;
|
||||
@@ -58,6 +59,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
this.paletteInfoPropertyKey = paletteInfoPropertyKey;
|
||||
this.noisePropertiesKey = noisePropertiesKey;
|
||||
this.slantCalculationMethod = slantCalculationMethod;
|
||||
this.useSlantPalettes = useSlantPalettes;
|
||||
int maxBlend = pack
|
||||
.getBiomeProvider()
|
||||
.stream()
|
||||
@@ -71,7 +73,7 @@ public class NoiseChunkGenerator3D implements ChunkGenerator {
|
||||
|
||||
private Palette paletteAt(int x, int y, int z, Sampler3D sampler, BiomePaletteInfo paletteInfo, int depth) {
|
||||
SlantHolder slantHolder = paletteInfo.slantHolder();
|
||||
if(slantHolder.isAboveDepth(depth)) {
|
||||
if(useSlantPalettes && slantHolder.isAboveDepth(depth)) {
|
||||
double slant = slantCalculationMethod.slant(sampler, x, y, z);
|
||||
if(slantHolder.isInSlantThreshold(slant)) {
|
||||
return slantHolder.getPalette(slant).getPalette(y);
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.addons;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
@@ -30,7 +30,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("addons", ArgumentDescription.of("List installed Terra addons"))
|
||||
manager.commandBuilder("addons", Description.of("List installed Terra addons"))
|
||||
.permission("terra.addons")
|
||||
.handler(context -> {
|
||||
StringBuilder addons = new StringBuilder("Installed addons:\n");
|
||||
@@ -41,7 +41,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(addon.getVersion().getFormatted())
|
||||
.append('\n'));
|
||||
context.getSender().sendMessage(addons.toString());
|
||||
context.sender().sendMessage(addons.toString());
|
||||
})
|
||||
)
|
||||
.command(
|
||||
@@ -61,7 +61,7 @@ public class AddonsCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(versions.getFormatted())
|
||||
.append('\n'));
|
||||
context.getSender().sendMessage(addonInfo.toString());
|
||||
context.sender().sendMessage(addonInfo.toString());
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
+10
-10
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.packs;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -35,7 +35,7 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("packs", ArgumentDescription.of("List installed config packs"))
|
||||
manager.commandBuilder("packs", Description.of("List installed config packs"))
|
||||
.permission("terra.packs")
|
||||
.handler(context -> {
|
||||
StringBuilder packs = new StringBuilder("Installed packs:\n");
|
||||
@@ -43,12 +43,12 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
.append(pack.getID())
|
||||
.append('@')
|
||||
.append(pack.getVersion().getFormatted()));
|
||||
context.getSender().sendMessage(packs.toString());
|
||||
context.sender().sendMessage(packs.toString());
|
||||
})
|
||||
)
|
||||
.command(
|
||||
manager.commandBuilder("packs")
|
||||
.literal("info", ArgumentDescription.of("Get information about a pack"))
|
||||
.literal("info", Description.of("Get information about a pack"))
|
||||
.permission("terra.packs.info")
|
||||
.argument(RegistryArgument.of("pack", platform.getConfigRegistry()))
|
||||
.handler(context -> {
|
||||
@@ -65,21 +65,21 @@ public class PacksCommandAddon implements AddonInitializer {
|
||||
.append('@')
|
||||
.append(versions.getFormatted())
|
||||
.append('\n'));
|
||||
context.getSender().sendMessage(packInfo.toString());
|
||||
context.sender().sendMessage(packInfo.toString());
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("packs")
|
||||
.literal("reload", ArgumentDescription.of("Reload config packs"))
|
||||
.literal("reload", Description.of("Reload config packs"))
|
||||
.permission("terra.packs.reload")
|
||||
.handler(context -> {
|
||||
context.getSender().sendMessage("Reloading Terra...");
|
||||
context.sender().sendMessage("Reloading Terra...");
|
||||
logger.info("Reloading Terra...");
|
||||
if(platform.reload()) {
|
||||
logger.info("Terra reloaded successfully.");
|
||||
context.getSender().sendMessage("Terra reloaded successfully.");
|
||||
context.sender().sendMessage("Terra reloaded successfully.");
|
||||
} else {
|
||||
logger.error("Terra failed to reload.");
|
||||
context.getSender().sendMessage(
|
||||
context.sender().sendMessage(
|
||||
"Terra failed to reload. See logs for more information.");
|
||||
}
|
||||
}));
|
||||
|
||||
+14
-14
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.commands.profiler;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -33,24 +33,24 @@ public class ProfilerCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
manager
|
||||
.command(
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("start", ArgumentDescription.of("Start profiling"), "st")
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("start", Description.of("Start profiling"), "st")
|
||||
.permission("terra.profiler.start")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().start();
|
||||
context.getSender().sendMessage("Profiling started.");
|
||||
context.sender().sendMessage("Profiling started.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("stop", ArgumentDescription.of("Stop profiling"), "s")
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("stop", Description.of("Stop profiling"), "s")
|
||||
.permission("terra.profiler.stop")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().stop();
|
||||
context.getSender().sendMessage("Profiling stopped.");
|
||||
context.sender().sendMessage("Profiling stopped.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("query", ArgumentDescription.of("Query profiler results"), "q")
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("query", Description.of("Query profiler results"), "q")
|
||||
.permission("terra.profiler.query")
|
||||
.handler(context -> {
|
||||
StringBuilder data = new StringBuilder("Terra Profiler data: \n");
|
||||
@@ -59,15 +59,15 @@ public class ProfilerCommandAddon implements AddonInitializer {
|
||||
.append(timings.toString())
|
||||
.append('\n'));
|
||||
logger.info(data.toString());
|
||||
context.getSender().sendMessage("Profiling data dumped to console.");
|
||||
context.sender().sendMessage("Profiling data dumped to console.");
|
||||
}))
|
||||
.command(
|
||||
manager.commandBuilder("profiler", ArgumentDescription.of("Access the profiler"))
|
||||
.literal("reset", ArgumentDescription.of("Reset the profiler"), "r")
|
||||
manager.commandBuilder("profiler", Description.of("Access the profiler"))
|
||||
.literal("reset", Description.of("Reset the profiler"), "r")
|
||||
.permission("terra.profiler.reset")
|
||||
.handler(context -> {
|
||||
platform.getProfiler().reset();
|
||||
context.getSender().sendMessage("Profiler reset.");
|
||||
context.sender().sendMessage("Profiler reset.");
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
+14
-18
@@ -1,13 +1,13 @@
|
||||
package com.dfsek.terra.addons.commands.structure;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.arguments.standard.EnumArgument;
|
||||
import cloud.commandframework.arguments.standard.LongArgument;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import org.incendo.cloud.CommandManager;
|
||||
import org.incendo.cloud.component.DefaultValue;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.description.Description;
|
||||
import org.incendo.cloud.parser.standard.EnumParser;
|
||||
import org.incendo.cloud.parser.standard.LongParser;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
|
||||
import com.dfsek.terra.api.Platform;
|
||||
@@ -32,7 +32,7 @@ public class StructureCommandAddon implements AddonInitializer {
|
||||
private BaseAddon addon;
|
||||
|
||||
private static Registry<Structure> getStructureRegistry(CommandContext<CommandSender> sender) {
|
||||
return sender.getSender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class);
|
||||
return sender.sender().getEntity().orElseThrow().world().getPack().getRegistry(Structure.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,24 +44,20 @@ public class StructureCommandAddon implements AddonInitializer {
|
||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||
|
||||
manager.command(
|
||||
manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures"))
|
||||
manager.commandBuilder("structures", Description.of("Manage or generate structures"))
|
||||
.literal("generate")
|
||||
.argument(RegistryArgument.builder("structure",
|
||||
.optional(RegistryArgument.builder("structure",
|
||||
StructureCommandAddon::getStructureRegistry,
|
||||
TypeKey.of(Structure.class)))
|
||||
.argument(LongArgument.optional("seed", 0))
|
||||
.argument(EnumArgument.optional(Rotation.class, "rotation", Rotation.NONE))
|
||||
.optional("seed", LongParser.longParser(), DefaultValue.constant(0L))
|
||||
.optional("rotation", EnumParser.enumParser(Rotation.class), DefaultValue.constant(Rotation.NONE))
|
||||
.handler(context -> {
|
||||
Structure structure = context.get("structure");
|
||||
Entity sender = context.getSender().getEntity().orElseThrow();
|
||||
Entity sender = context.sender().getEntity().orElseThrow();
|
||||
structure.generate(
|
||||
sender.position().toInt(),
|
||||
sender.world(),
|
||||
((Long) context.get("seed") == 0)
|
||||
? RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
||||
.create()
|
||||
: RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
||||
.create(context.get("seed")),
|
||||
((Long) context.get("seed") == 0) ? new Random() : new Random(context.get("seed")),
|
||||
context.get("rotation")
|
||||
);
|
||||
})
|
||||
|
||||
+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
-4
@@ -1,7 +1,6 @@
|
||||
package com.dfsek.terra.addons.feature.distributor.distributors;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.structure.feature.Distributor;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
@@ -25,8 +24,7 @@ public class PaddedGridDistributor implements Distributor {
|
||||
int cellX = Math.floorDiv(x, cellWidth);
|
||||
int cellZ = Math.floorDiv(z, cellWidth);
|
||||
|
||||
RandomGenerator random = RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus").create(
|
||||
(MathUtil.murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt);
|
||||
Random random = new Random((MathUtil.murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt);
|
||||
|
||||
int pointX = random.nextInt(width) + cellX * cellWidth;
|
||||
int pointZ = random.nextInt(width) + cellZ * cellWidth;
|
||||
|
||||
+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;
|
||||
|
||||
+3
-6
@@ -10,8 +10,7 @@ package com.dfsek.terra.addons.flora.flora.gen;
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.block.state.properties.enums.Direction;
|
||||
@@ -72,7 +71,7 @@ public class TerraFlora implements Structure {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
boolean doRotation = testRotation.size() > 0;
|
||||
int size = layers.size();
|
||||
int c = ceiling ? -1 : 1;
|
||||
@@ -87,9 +86,7 @@ public class TerraFlora implements Structure {
|
||||
location.getZ(), world.getSeed());
|
||||
if(doRotation) {
|
||||
Direction oneFace = new ArrayList<>(faces).get(
|
||||
RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
||||
.create(location.getX() ^ location.getZ())
|
||||
.nextInt(faces.size())); // Get RandomGenerator face.
|
||||
new Random(location.getX() ^ location.getZ()).nextInt(faces.size())); // Get random face.
|
||||
}
|
||||
world.setBlockState(location.mutable().add(0, i + c, 0).immutable(), data, physics);
|
||||
}
|
||||
|
||||
+2
-3
@@ -7,8 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.feature.locator.locators;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.structure.feature.BinaryColumn;
|
||||
import com.dfsek.terra.api.structure.feature.Locator;
|
||||
@@ -41,7 +40,7 @@ public class GaussianRandomLocator implements Locator {
|
||||
seed = 31 * seed + column.getZ();
|
||||
seed += salt;
|
||||
|
||||
RandomGenerator r = RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus").create(seed);
|
||||
Random r = new Random(seed);
|
||||
|
||||
int size = points.get(r);
|
||||
|
||||
|
||||
+2
-3
@@ -7,8 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.feature.locator.locators;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.structure.feature.BinaryColumn;
|
||||
import com.dfsek.terra.api.structure.feature.Locator;
|
||||
@@ -37,7 +36,7 @@ public class RandomLocator implements Locator {
|
||||
seed = 31 * seed + column.getZ();
|
||||
seed += salt;
|
||||
|
||||
RandomGenerator r = RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus").create(seed);
|
||||
Random r = new Random(seed);
|
||||
|
||||
int size = points.get(r);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version = version("1.1.0")
|
||||
version = version("1.2.0")
|
||||
|
||||
dependencies {
|
||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||
|
||||
+11
-2
@@ -17,6 +17,8 @@ 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;
|
||||
@@ -28,6 +30,7 @@ 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;
|
||||
@@ -35,6 +38,7 @@ 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;
|
||||
@@ -63,6 +67,7 @@ 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;
|
||||
@@ -94,9 +99,11 @@ 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(CubicSpline.Point.class, CubicSplinePointTemplate::new)
|
||||
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::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);
|
||||
@@ -117,7 +124,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));
|
||||
@@ -144,6 +151,8 @@ 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"), CacheSamplerTemplate::new);
|
||||
|
||||
|
||||
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 {
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
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<CacheSampler> {
|
||||
@Value("sampler")
|
||||
@Default
|
||||
private NoiseSampler sampler;
|
||||
|
||||
public CacheSamplerTemplate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public NoiseSampler get() {
|
||||
return new CacheSampler(sampler, getDimensions());
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
import com.dfsek.tectonic.api.exception.ValidationException;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class DerivativeNoiseSamplerTemplate extends SamplerTemplate<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;
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -34,7 +34,11 @@ 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();
|
||||
@@ -44,6 +48,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
|
||||
sampler.setReturnType(cellularReturnType);
|
||||
sampler.setDistanceFunction(cellularDistanceFunction);
|
||||
sampler.setSalt(salt);
|
||||
sampler.setSaltLookup(saltLookup);
|
||||
return sampler;
|
||||
}
|
||||
}
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
|
||||
|
||||
public abstract class DerivativeNoiseTemplate<T extends DerivativeNoiseFunction> extends NoiseTemplate<T> {
|
||||
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.PseudoErosionSampler;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
|
||||
|
||||
public class PseudoErosionTemplate extends NoiseTemplate<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
@@ -0,0 +1,31 @@
|
||||
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
@@ -0,0 +1,28 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
+11
-4
@@ -11,6 +11,8 @@ 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 {
|
||||
@@ -23,10 +25,15 @@ public class FunctionUtil {
|
||||
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
|
||||
functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
|
||||
}
|
||||
samplers.forEach((id, sampler) -> functionMap.put(id,
|
||||
sampler.getDimensions() == 2 ?
|
||||
new NoiseFunction2(sampler.getSampler()) :
|
||||
new NoiseFunction3(sampler.getSampler())));
|
||||
samplers.forEach((id, sampler) -> {
|
||||
if(sampler.getDimensions() == 2) {
|
||||
functionMap.put(id, new NoiseFunction2(sampler.getSampler()));
|
||||
functionMap.put(id + "Salted", new SaltedNoiseFunction2(sampler.getSampler()));
|
||||
} else {
|
||||
functionMap.put(id, new NoiseFunction3(sampler.getSampler()));
|
||||
functionMap.put(id + "Salted", new SaltedNoiseFunction3(sampler.getSampler()));
|
||||
}
|
||||
});
|
||||
return functionMap;
|
||||
}
|
||||
}
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class SaltedNoiseFunction2 implements DynamicFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public SaltedNoiseFunction2(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(Context context, double... args) {
|
||||
return gen.noise(((SeedContext) context).getSeed() + (long) args[2], args[0], args[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
package com.dfsek.terra.addons.noise.paralithic.noise;
|
||||
|
||||
import com.dfsek.paralithic.functions.dynamic.Context;
|
||||
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
|
||||
import com.dfsek.paralithic.node.Statefulness;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class SaltedNoiseFunction3 implements DynamicFunction {
|
||||
private final NoiseSampler gen;
|
||||
|
||||
public SaltedNoiseFunction3(NoiseSampler gen) {
|
||||
this.gen = gen;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(double... args) {
|
||||
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public double eval(Context context, double... args) {
|
||||
return gen.noise(((SeedContext) context).getSeed() + (long) args[3], args[0], args[1], args[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArgNumber() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Statefulness statefulness() {
|
||||
return Statefulness.CONTEXTUAL;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
package com.dfsek.terra.addons.noise.samplers;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
import com.dfsek.terra.api.util.cache.DoubleSeededVector2Key;
|
||||
import com.dfsek.terra.api.util.cache.DoubleSeededVector3Key;
|
||||
import com.dfsek.terra.api.util.generic.pair.Pair;
|
||||
|
||||
import com.dfsek.terra.api.util.generic.pair.Pair.Mutable;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.github.benmanes.caffeine.cache.Scheduler;
|
||||
|
||||
import static com.dfsek.terra.api.util.cache.CacheUtils.CACHE_EXECUTOR;
|
||||
|
||||
|
||||
public class CacheSampler implements NoiseSampler {
|
||||
|
||||
private final NoiseSampler sampler;
|
||||
private final ThreadLocal<Mutable<DoubleSeededVector2Key, LoadingCache<DoubleSeededVector2Key, Double>>> cache2D;
|
||||
private final ThreadLocal<Mutable<DoubleSeededVector3Key, LoadingCache<DoubleSeededVector3Key, Double>>> cache3D;
|
||||
|
||||
public CacheSampler(NoiseSampler sampler, int dimensions) {
|
||||
this.sampler = sampler;
|
||||
if (dimensions == 2) {
|
||||
LoadingCache<DoubleSeededVector2Key, Double> cache = Caffeine
|
||||
.newBuilder()
|
||||
.executor(CACHE_EXECUTOR)
|
||||
.scheduler(Scheduler.systemScheduler())
|
||||
.initialCapacity(256)
|
||||
.maximumSize(256)
|
||||
.build(this::sampleNoise);
|
||||
this.cache2D = ThreadLocal.withInitial(() -> Pair.of(new DoubleSeededVector2Key(0, 0, 0), cache).mutable());
|
||||
this.cache3D = null;
|
||||
} else {
|
||||
LoadingCache<DoubleSeededVector3Key, Double> cache = Caffeine
|
||||
.newBuilder()
|
||||
.executor(CACHE_EXECUTOR)
|
||||
.scheduler(Scheduler.systemScheduler())
|
||||
.initialCapacity(981504)
|
||||
.maximumSize(981504)
|
||||
.build(this::sampleNoise);
|
||||
this.cache3D = ThreadLocal.withInitial(() -> Pair.of(new DoubleSeededVector3Key(0, 0, 0, 0), cache).mutable());
|
||||
this.cache2D = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Double sampleNoise(DoubleSeededVector2Key vec) {
|
||||
this.cache2D.get().setLeft(new DoubleSeededVector2Key(0, 0, 0));
|
||||
return this.sampler.noise(vec.seed, vec.x, vec.z);
|
||||
}
|
||||
|
||||
private Double sampleNoise(DoubleSeededVector3Key vec) {
|
||||
this.cache3D.get().setLeft(new DoubleSeededVector3Key(0, 0, 0, 0));
|
||||
return this.sampler.noise(vec.seed, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y) {
|
||||
Mutable<DoubleSeededVector2Key, LoadingCache<DoubleSeededVector2Key, Double>> cachePair = cache2D.get();
|
||||
DoubleSeededVector2Key mutableKey = cachePair.getLeft();
|
||||
mutableKey.set(x, y, seed);
|
||||
return cachePair.getRight().get(mutableKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(long seed, double x, double y, double z) {
|
||||
Mutable<DoubleSeededVector3Key, LoadingCache<DoubleSeededVector3Key, Double>> cachePair = cache3D.get();
|
||||
DoubleSeededVector3Key mutableKey = cachePair.getLeft();
|
||||
mutableKey.set(x, y, z, seed);
|
||||
return cachePair.getRight().get(mutableKey);
|
||||
}
|
||||
}
|
||||
+10
@@ -12,4 +12,14 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-1
@@ -1,9 +1,10 @@
|
||||
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 NoiseSampler {
|
||||
public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler {
|
||||
private final NoiseSampler left;
|
||||
private final NoiseSampler right;
|
||||
|
||||
@@ -12,6 +13,11 @@ public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
||||
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));
|
||||
@@ -22,5 +28,17 @@ public abstract class BinaryArithmeticSampler implements NoiseSampler {
|
||||
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,4 +12,15 @@ 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,4 +12,11 @@ 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,4 +12,11 @@ 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,4 +12,15 @@ 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,4 +12,14 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
+12
-6
@@ -197,7 +197,9 @@ public class CellularSampler extends NoiseFunction {
|
||||
private double jitterModifier = 1.0;
|
||||
|
||||
private NoiseSampler noiseLookup;
|
||||
|
||||
|
||||
private boolean saltLookup;
|
||||
|
||||
public CellularSampler() {
|
||||
noiseLookup = new OpenSimplex2Sampler();
|
||||
}
|
||||
@@ -217,7 +219,11 @@ 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;
|
||||
@@ -286,8 +292,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, centerX, centerY);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY);
|
||||
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 Distance3 -> distance2 - 1;
|
||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub -> distance2 - distance0 - 1;
|
||||
@@ -377,8 +383,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, centerX, centerY, centerZ);
|
||||
case LocalNoiseLookup -> noiseLookup.noise(sl, x / frequency - centerX, y / frequency - centerY, z / frequency - centerZ);
|
||||
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 Distance3 -> distance2 - 1;
|
||||
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
|
||||
case Distance3Sub -> distance2 - distance0 - 1;
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
|
||||
|
||||
public abstract class DerivativeNoiseFunction extends NoiseFunction implements DerivativeNoiseSampler {
|
||||
@Override
|
||||
public boolean isDifferentiable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y) {
|
||||
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] noised(long seed, double x, double y, double z) {
|
||||
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency, z * frequency);
|
||||
}
|
||||
|
||||
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y);
|
||||
|
||||
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y, double z);
|
||||
}
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
package com.dfsek.terra.addons.noise.samplers.noise;
|
||||
|
||||
|
||||
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
|
||||
import com.dfsek.terra.api.util.MathUtil;
|
||||
|
||||
|
||||
public class PseudoErosionSampler extends NoiseFunction {
|
||||
public static final double TAU = 2.0 * Math.PI;
|
||||
private static final double HASH_X = 0.3183099f;
|
||||
private static final double HASH_Y = 0.3678794f;
|
||||
public final double gain;
|
||||
public final double lacunarity;
|
||||
public final double slopeStrength;
|
||||
public final double branchStrength;
|
||||
public final double erosionStrength;
|
||||
private final int octaves;
|
||||
private final double erosionFrequency;
|
||||
private final DerivativeNoiseSampler sampler;
|
||||
private final boolean slopeMask;
|
||||
private final double slopeMaskFullSq;
|
||||
private final double slopeMaskNoneSq;
|
||||
private final double jitter;
|
||||
private final double maxCellDistSq;
|
||||
private final double maxCellDistSqRecip;
|
||||
private final boolean averageErosionImpulses;
|
||||
|
||||
public PseudoErosionSampler(int octaves, double gain, double lacunarity, double slopeStrength, double branchStrength,
|
||||
double erosionStrength, double erosionFrequency, DerivativeNoiseSampler sampler,
|
||||
boolean slopeMask, double slopeMaskFull, double slopeMaskNone, double jitterModifier,
|
||||
boolean averageErosionImpulses) {
|
||||
this.octaves = octaves;
|
||||
this.gain = gain;
|
||||
this.lacunarity = lacunarity;
|
||||
this.slopeStrength = slopeStrength;
|
||||
this.branchStrength = branchStrength;
|
||||
this.erosionStrength = erosionStrength;
|
||||
this.erosionFrequency = erosionFrequency;
|
||||
this.sampler = sampler;
|
||||
this.slopeMask = slopeMask;
|
||||
// Square these values and maintain sign since they're compared to a
|
||||
// squared value, otherwise a sqrt would need to be used
|
||||
this.slopeMaskFullSq = slopeMaskFull * slopeMaskFull * Math.signum(slopeMaskFull);
|
||||
this.slopeMaskNoneSq = slopeMaskNone * slopeMaskNone * Math.signum((slopeMaskNone));
|
||||
this.jitter = 0.43701595 * jitterModifier;
|
||||
this.averageErosionImpulses = averageErosionImpulses;
|
||||
this.maxCellDistSq = 1 + jitter * jitter;
|
||||
this.maxCellDistSqRecip = 1 / maxCellDistSq;
|
||||
}
|
||||
|
||||
public static double hashX(double seed, double n) {
|
||||
// Swapped the components here
|
||||
double nx = HASH_X * n * seed;
|
||||
return -1.0f + 2.0f * fract(nx);
|
||||
}
|
||||
|
||||
public static double hashY(double seed, double n) {
|
||||
double ny = HASH_Y * n * seed;
|
||||
return -1.0f + 2.0f * fract(ny);
|
||||
}
|
||||
|
||||
public static double fract(double x) {
|
||||
return (x - Math.floor(x));
|
||||
}
|
||||
|
||||
public static double smoothstep(double edge0, double edge1, double x) {
|
||||
// Scale, bias and saturate x to 0..1 range
|
||||
x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
|
||||
// Evaluate polynomial
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
public static double clamp(double x, double minVal, double maxVal) {
|
||||
return Math.max(minVal, Math.min(maxVal, x));
|
||||
}
|
||||
|
||||
public static double dot(double x1, double y1, double x2, double y2) {
|
||||
return x1 * x2 + y1 * y2;
|
||||
}
|
||||
|
||||
public double[] erosion(int seed, double x, double y, double dirX, double dirY) {
|
||||
int gridX = (int) Math.round(x);
|
||||
int gridY = (int) Math.round(y);
|
||||
double noise = 0.0f;
|
||||
double dirOutX = 0.0f;
|
||||
double dirOutY = 0.0f;
|
||||
double cumAmp = 0.0f;
|
||||
|
||||
for(int cellX = gridX - 1; cellX <= gridX + 1; cellX++) {
|
||||
for(int cellY = gridY - 1; cellY <= gridY + 1; cellY++) {
|
||||
double cellHash = hash(seed, cellX, cellY);
|
||||
double cellOffsetX = hashX(seed, cellHash) * jitter;
|
||||
double cellOffsetY = hashY(seed, cellHash) * jitter;
|
||||
double cellOriginDeltaX = (x - cellX) + cellOffsetX;
|
||||
double cellOriginDeltaY = (y - cellY) + cellOffsetY;
|
||||
double cellOriginDistSq = cellOriginDeltaX * cellOriginDeltaX + cellOriginDeltaY * cellOriginDeltaY;
|
||||
if(cellOriginDistSq > maxCellDistSq) continue; // Skip calculating cells too far away
|
||||
double ampTmp = (cellOriginDistSq * maxCellDistSqRecip) - 1;
|
||||
double amp = ampTmp * ampTmp; // Decrease cell amplitude further away
|
||||
cumAmp += amp;
|
||||
double directionalStrength = dot(cellOriginDeltaX, cellOriginDeltaY, dirX, dirY) * TAU;
|
||||
noise += MathUtil.cos(directionalStrength) * amp;
|
||||
double sinAngle = MathUtil.sin(directionalStrength) * amp;
|
||||
dirOutX -= sinAngle * (cellOriginDeltaX + dirX);
|
||||
dirOutY -= sinAngle * (cellOriginDeltaY + dirY);
|
||||
}
|
||||
}
|
||||
if(averageErosionImpulses && cumAmp != 0) {
|
||||
noise /= cumAmp;
|
||||
dirOutX /= cumAmp;
|
||||
dirOutY /= cumAmp;
|
||||
}
|
||||
return new double[]{ noise, dirOutX, dirOutY };
|
||||
}
|
||||
|
||||
public double heightMap(long seed, double x, double y) {
|
||||
double[] sample = sampler.noised(seed, x, y);
|
||||
double height = sample[0];
|
||||
double heightDirX = sample[1];
|
||||
double heightDirY = sample[2];
|
||||
|
||||
// Take the curl of the normal to get the gradient facing down the slope
|
||||
double baseDirX = heightDirY * slopeStrength;
|
||||
double baseDirY = -heightDirX * slopeStrength;
|
||||
|
||||
double erosion = 0.0f;
|
||||
double dirX = 0.0f;
|
||||
double dirY = 0.0f;
|
||||
double amp = 1.0f;
|
||||
double cumAmp = 0.0f;
|
||||
double freq = 1.0f;
|
||||
|
||||
// Stack erosion octaves
|
||||
for(int i = 0; i < octaves; i++) {
|
||||
double[] erosionResult = erosion((int) seed,
|
||||
x * freq * erosionFrequency,
|
||||
y * freq * erosionFrequency,
|
||||
baseDirX + dirY * branchStrength,
|
||||
baseDirY - dirX * branchStrength);
|
||||
erosion += erosionResult[0] * amp;
|
||||
dirX += erosionResult[1] * amp * freq;
|
||||
dirY += erosionResult[2] * amp * freq;
|
||||
cumAmp += amp;
|
||||
amp *= gain;
|
||||
freq *= lacunarity;
|
||||
}
|
||||
|
||||
// Normalize erosion noise
|
||||
erosion /= cumAmp;
|
||||
// [-1, 1] -> [0, 1]
|
||||
erosion = erosion * 0.5F + 0.5F;
|
||||
|
||||
// Without masking, erosion noise in areas with small gradients tend to produce mounds,
|
||||
// this reduces erosion amplitude towards smaller gradients to avoid this
|
||||
if(slopeMask) {
|
||||
double dirMagSq = dot(baseDirX, baseDirY, baseDirX, baseDirY);
|
||||
double flatness = smoothstep((double) slopeMaskNoneSq, slopeMaskFullSq, dirMagSq);
|
||||
erosion *= flatness;
|
||||
}
|
||||
|
||||
return height + erosion * erosionStrength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y) {
|
||||
return heightMap(seed, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getNoiseRaw(long seed, double x, double y, double z) {
|
||||
return getNoiseRaw(seed, x, z);
|
||||
}
|
||||
}
|
||||
+57
@@ -7,6 +7,7 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -52,4 +53,60 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
|
||||
|
||||
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);
|
||||
|
||||
x *= lacunarity;
|
||||
y *= lacunarity;
|
||||
z *= lacunarity;
|
||||
amp *= gain;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
+17
-2
@@ -7,11 +7,11 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public abstract class FractalNoiseFunction extends NoiseFunction {
|
||||
public abstract class FractalNoiseFunction extends DerivativeNoiseFunction {
|
||||
protected final NoiseSampler input;
|
||||
protected double fractalBounding = 1 / 1.75;
|
||||
protected int octaves = 3;
|
||||
@@ -52,4 +52,19 @@ public abstract class FractalNoiseFunction extends NoiseFunction {
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
+420
@@ -276,4 +276,424 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
+214
-14
@@ -37,41 +37,37 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
|
||||
i *= PRIME_X;
|
||||
j *= PRIME_Y;
|
||||
|
||||
double n0, n1, n2;
|
||||
double value = 0;
|
||||
|
||||
double a = 0.5 - x0 * x0 - y0 * y0;
|
||||
if(a <= 0) n0 = 0;
|
||||
else {
|
||||
n0 = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
|
||||
if(a > 0) {
|
||||
value = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
|
||||
}
|
||||
|
||||
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
|
||||
if(c <= 0) n2 = 0;
|
||||
else {
|
||||
if(c > 0) {
|
||||
double x2 = x0 + (2 * G2 - 1);
|
||||
double y2 = y0 + (2 * G2 - 1);
|
||||
n2 = (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
|
||||
value += (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
|
||||
}
|
||||
|
||||
if(y0 > x0) {
|
||||
double x1 = x0 + G2;
|
||||
double y1 = y0 + (G2 - 1);
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
|
||||
if(b > 0) {
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
|
||||
}
|
||||
} else {
|
||||
double x1 = x0 + (G2 - 1);
|
||||
double y1 = y0 + G2;
|
||||
double b = 0.5 - x1 * x1 - y1 * y1;
|
||||
if(b <= 0) n1 = 0;
|
||||
else {
|
||||
n1 = (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
|
||||
if(b > 0) {
|
||||
value += (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
|
||||
}
|
||||
}
|
||||
|
||||
return (n0 + n1 + n2) * 99.83685446303647f;
|
||||
return value * 99.83685446303647f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,4 +153,208 @@ public 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;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-9
@@ -7,13 +7,13 @@
|
||||
|
||||
package com.dfsek.terra.addons.noise.samplers.noise.simplex;
|
||||
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
|
||||
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract NoiseSampler implementation for simplex-style noise functions.
|
||||
*/
|
||||
public abstract class SimplexStyleSampler extends NoiseFunction {
|
||||
public abstract class SimplexStyleSampler extends DerivativeNoiseFunction {
|
||||
protected static final double[] GRADIENTS_2_D = {
|
||||
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
|
||||
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
|
||||
@@ -79,26 +79,53 @@ public abstract class SimplexStyleSampler extends NoiseFunction {
|
||||
1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0
|
||||
};
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
|
||||
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed) {
|
||||
int hash = hash(seed, xPrimed, yPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 127 << 1;
|
||||
|
||||
double xg = GRADIENTS_2_D[hash];
|
||||
double yg = GRADIENTS_2_D[hash | 1];
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
|
||||
int index = gradCoordIndex(seed, xPrimed, yPrimed);
|
||||
|
||||
double xg = GRADIENTS_2_D[index];
|
||||
double yg = GRADIENTS_2_D[index | 1];
|
||||
|
||||
return xd * xg + yd * yg;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
|
||||
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed, int zPrimed) {
|
||||
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
|
||||
hash ^= hash >> 15;
|
||||
hash &= 63 << 2;
|
||||
|
||||
double xg = GRADIENTS_3D[hash];
|
||||
double yg = GRADIENTS_3D[hash | 1];
|
||||
double zg = GRADIENTS_3D[hash | 2];
|
||||
return hash;
|
||||
}
|
||||
|
||||
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
|
||||
int index = gradCoordIndex(seed, xPrimed, yPrimed, zPrimed);
|
||||
|
||||
double xg = GRADIENTS_3D[index];
|
||||
double yg = GRADIENTS_3D[index | 1];
|
||||
double zg = GRADIENTS_3D[index | 2];
|
||||
|
||||
return xd * xg + yd * yg + zd * zg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ package com.dfsek.terra.addons.ore.ores;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.Map;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
@@ -44,7 +44,7 @@ public class VanillaOre implements Structure {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
float randomRadian = random.nextFloat() * (float) Math.PI;
|
||||
double eighthSize = size / 8.0F;
|
||||
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
package com.dfsek.terra.addons.ore.ores;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
@@ -24,7 +24,7 @@ public class VanillaScatteredOre extends VanillaOre {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
int i = random.nextInt((int) (size + 1));
|
||||
Vector3Int.Mutable mutable = Vector3Int.zero().mutable();
|
||||
|
||||
@@ -39,7 +39,7 @@ public class VanillaScatteredOre extends VanillaOre {
|
||||
return true;
|
||||
}
|
||||
|
||||
private void setPos(Vector3Int.Mutable mutable, RandomGenerator random, Vector3Int location, int spread) {
|
||||
private void setPos(Vector3Int.Mutable mutable, Random random, Vector3Int location, int spread) {
|
||||
int x = this.getSpread(random, spread);
|
||||
int y = this.getSpread(random, spread);
|
||||
int z = this.getSpread(random, spread);
|
||||
@@ -48,7 +48,7 @@ public class VanillaScatteredOre extends VanillaOre {
|
||||
mutable.setZ(location.getZ() + z);
|
||||
}
|
||||
|
||||
private int getSpread(RandomGenerator random, int spread) {
|
||||
private int getSpread(Random random, int spread) {
|
||||
return Math.round((random.nextFloat() - random.nextFloat()) * (float) spread);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-4
@@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.addons.ore.utils;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.BlockType;
|
||||
import com.dfsek.terra.api.util.collection.MaterialSet;
|
||||
@@ -8,14 +8,13 @@ import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
|
||||
public class VanillaOreUtils {
|
||||
private static boolean shouldExpose(RandomGenerator random, double exposedChance) {
|
||||
private static boolean shouldExpose(Random random, double exposedChance) {
|
||||
if(exposedChance >= 1.0F) return true;
|
||||
if(exposedChance <= 0.0F) return false;
|
||||
return random.nextFloat() < exposedChance;
|
||||
}
|
||||
|
||||
public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposedChance, RandomGenerator random,
|
||||
WritableWorld world,
|
||||
public static boolean shouldPlace(MaterialSet replaceable, BlockType type, Double exposedChance, Random random, WritableWorld world,
|
||||
int x,
|
||||
int y, int z) {
|
||||
if(!replaceable.contains(type)) return false;
|
||||
|
||||
+3
-3
@@ -12,7 +12,7 @@ import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.structure.structures.loot.functions.AmountFunction;
|
||||
import com.dfsek.terra.addons.structure.structures.loot.functions.DamageFunction;
|
||||
@@ -85,11 +85,11 @@ public class Entry {
|
||||
/**
|
||||
* Fetches a single ItemStack from the Entry, applying all functions to it.
|
||||
*
|
||||
* @param r The RandomGenerator instance to apply functions with
|
||||
* @param r The Random instance to apply functions with
|
||||
*
|
||||
* @return ItemStack - The ItemStack with all functions applied.
|
||||
*/
|
||||
public ItemStack getItem(RandomGenerator r) {
|
||||
public ItemStack getItem(Random r) {
|
||||
ItemStack item = this.item.newItemStack(1);
|
||||
for(LootFunction f : functions) {
|
||||
item = f.apply(item, r);
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ import org.json.simple.parser.ParseException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.inventory.Inventory;
|
||||
@@ -44,7 +44,7 @@ public class LootTableImpl implements com.dfsek.terra.api.structure.LootTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillInventory(Inventory i, RandomGenerator r) {
|
||||
public void fillInventory(Inventory i, Random r) {
|
||||
List<ItemStack> loot = getLoot(r);
|
||||
for(ItemStack stack : loot) {
|
||||
int attempts = 0;
|
||||
@@ -70,7 +70,7 @@ public class LootTableImpl implements com.dfsek.terra.api.structure.LootTable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemStack> getLoot(RandomGenerator r) {
|
||||
public List<ItemStack> getLoot(Random r) {
|
||||
List<ItemStack> itemList = new ArrayList<>();
|
||||
for(Pool pool : pools) {
|
||||
itemList.addAll(pool.getItems(r));
|
||||
|
||||
+4
-4
@@ -12,7 +12,7 @@ import org.json.simple.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
@@ -50,13 +50,13 @@ public class Pool {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a list of items from the pool using the provided RandomGenerator instance.
|
||||
* Fetches a list of items from the pool using the provided Random instance.
|
||||
*
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return List<ItemStack> - The list of items fetched.
|
||||
*/
|
||||
public List<ItemStack> getItems(RandomGenerator r) {
|
||||
public List<ItemStack> getItems(Random r) {
|
||||
|
||||
int rolls = r.nextInt(max - min + 1) + min;
|
||||
List<ItemStack> items = new ArrayList<>();
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
package com.dfsek.terra.addons.structure.structures.loot.functions;
|
||||
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
|
||||
@@ -35,12 +35,12 @@ public class AmountFunction implements LootFunction {
|
||||
* Applies the function to an ItemStack.
|
||||
*
|
||||
* @param original The ItemStack on which to apply the function.
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return - ItemStack - The mutated ItemStack.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack apply(ItemStack original, RandomGenerator r) {
|
||||
public ItemStack apply(ItemStack original, Random r) {
|
||||
original.setAmount(r.nextInt(max - min + 1) + min);
|
||||
return original;
|
||||
}
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.structure.structures.loot.functions;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
import com.dfsek.terra.api.inventory.item.Damageable;
|
||||
@@ -36,12 +36,12 @@ public class DamageFunction implements LootFunction {
|
||||
* Applies the function to an ItemStack.
|
||||
*
|
||||
* @param original The ItemStack on which to apply the function.
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return - ItemStack - The mutated ItemStack.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack apply(ItemStack original, RandomGenerator r) {
|
||||
public ItemStack apply(ItemStack original, Random r) {
|
||||
if(original == null) return null;
|
||||
if(!original.isDamageable()) return original;
|
||||
ItemMeta meta = original.getItemMeta();
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.Platform;
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
@@ -41,12 +41,12 @@ public class EnchantFunction implements LootFunction {
|
||||
* Applies the function to an ItemStack.
|
||||
*
|
||||
* @param original The ItemStack on which to apply the function.
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return - ItemStack - The mutated ItemStack.
|
||||
*/
|
||||
@Override
|
||||
public ItemStack apply(ItemStack original, RandomGenerator r) {
|
||||
public ItemStack apply(ItemStack original, Random r) {
|
||||
if(original.getItemMeta() == null) return original;
|
||||
|
||||
double enchant = (r.nextDouble() * (max - min)) + min;
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
package com.dfsek.terra.addons.structure.structures.loot.functions;
|
||||
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
|
||||
@@ -21,9 +21,9 @@ public interface LootFunction {
|
||||
* Applies the function to an ItemStack.
|
||||
*
|
||||
* @param original The ItemStack on which to apply the function.
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return - ItemStack - The mutated ItemStack.
|
||||
*/
|
||||
ItemStack apply(ItemStack original, RandomGenerator r);
|
||||
ItemStack apply(ItemStack original, Random r);
|
||||
}
|
||||
|
||||
+3
-7
@@ -11,13 +11,6 @@ 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;
|
||||
@@ -35,6 +28,9 @@ 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<>() {
|
||||
|
||||
+17
-9
@@ -7,12 +7,9 @@
|
||||
|
||||
package com.dfsek.terra.addons.generation.feature;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
|
||||
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;
|
||||
@@ -22,6 +19,9 @@ 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,13 +32,20 @@ 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) {
|
||||
public FeatureGenerationStage(Platform platform, String id, int resolution, PropertyKey<BiomeFeatures> biomeFeaturesKey,
|
||||
NoiseSampler blendSampler, double blendAmplitude) {
|
||||
this.platform = platform;
|
||||
this.id = id;
|
||||
this.profile = "feature_stage:" + id;
|
||||
this.resolution = resolution;
|
||||
this.biomeFeaturesKey = biomeFeaturesKey;
|
||||
this.blendSampler = blendSampler;
|
||||
this.doBlending = blendAmplitude != 0d;
|
||||
this.blendAmplitude = blendAmplitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,7 +60,10 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
||||
int tx = cx + chunkX;
|
||||
int tz = cz + chunkZ;
|
||||
world.getBiomeProvider()
|
||||
.getColumn(tx, tz, world)
|
||||
.getColumn(
|
||||
tx + (doBlending ? (int) (blendSampler.noise(seed, tx, tz) * blendAmplitude) : 0),
|
||||
tz + (doBlending ? (int) (blendSampler.noise(seed + 1, tx, tz) * blendAmplitude) : 0),
|
||||
world)
|
||||
.forRanges(resolution, (min, max, biome) -> {
|
||||
for(int subChunkX = 0; subChunkX < resolution; subChunkX++) {
|
||||
for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) {
|
||||
@@ -73,9 +83,7 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
||||
.forEach(y -> feature.getStructure(world, x, y, z)
|
||||
.generate(Vector3Int.of(x, y, z),
|
||||
world,
|
||||
RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of(
|
||||
"Xoroshiro128PlusPlus")
|
||||
.create(coordinateSeed * 31 + y),
|
||||
new Random(coordinateSeed * 31 + y),
|
||||
Rotation.NONE)
|
||||
);
|
||||
}
|
||||
|
||||
+20
-1
@@ -8,6 +8,7 @@ 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;
|
||||
|
||||
@@ -22,6 +23,24 @@ 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;
|
||||
@@ -30,7 +49,7 @@ public class FeatureStageTemplate implements ObjectTemplate<GenerationStage>, Va
|
||||
|
||||
@Override
|
||||
public FeatureGenerationStage get() {
|
||||
return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey);
|
||||
return new FeatureGenerationStage(platform, id, resolution, biomeFeaturesKey, blendSampler, blendAmplitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-19
@@ -11,16 +11,12 @@ 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 {
|
||||
@@ -37,21 +33,10 @@ public class YamlAddon implements AddonInitializer {
|
||||
platform.getEventManager()
|
||||
.getHandler(FunctionalEventHandler.class)
|
||||
.register(addon, ConfigurationDiscoveryEvent.class)
|
||||
.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);
|
||||
}
|
||||
})
|
||||
.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())
|
||||
.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));
|
||||
imageRegistry.register(addon.key("STITCHED_BITMAP"), () -> new StitchedImageTemplate(pack));
|
||||
imageRegistry.register(addon.key("BITMAP"), () -> new ImageTemplate(pack.getLoader(), pack));
|
||||
imageRegistry.register(addon.key("STITCHED_BITMAP"), () -> new StitchedImageTemplate(pack.getLoader(), pack));
|
||||
})
|
||||
.then(event -> {
|
||||
event.getPack()
|
||||
|
||||
+23
-10
@@ -4,10 +4,8 @@ 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;
|
||||
@@ -15,21 +13,27 @@ 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;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Scheduler;
|
||||
|
||||
import static com.dfsek.terra.api.util.cache.CacheUtils.CACHE_EXECUTOR;
|
||||
|
||||
|
||||
/*
|
||||
* 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) throws IOException {
|
||||
public static Image load(String path, ConfigPack pack, Loader files) 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, pack.getRootPath())));
|
||||
var cacheBuilder = Caffeine.newBuilder().executor(CACHE_EXECUTOR).scheduler(Scheduler.systemScheduler());
|
||||
if(config.unloadOnTimeout()) cacheBuilder.expireAfterAccess(config.getCacheTimeout(), TimeUnit.SECONDS) .executor(CACHE_EXECUTOR)
|
||||
.scheduler(Scheduler.systemScheduler());
|
||||
images = new ImageCache(cacheBuilder.build(s -> loadImage(s, files)));
|
||||
pack.getContext().put(images);
|
||||
} else images = pack.getContext().get(ImageCache.class);
|
||||
|
||||
@@ -46,8 +50,17 @@ record ImageCache(LoadingCache<String, Image> cache) implements Properties {
|
||||
return images.cache.get(path);
|
||||
}
|
||||
|
||||
private static Image loadImage(String path, Path directory) throws IOException {
|
||||
InputStream is = Files.newInputStream(directory.resolve(path));
|
||||
return new BufferedImageWrapper(ImageIO.read(is));
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -7,22 +7,25 @@ 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(ConfigPack pack) {
|
||||
public ImageTemplate(Loader files, ConfigPack pack) {
|
||||
this.files = files;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image get() {
|
||||
try {
|
||||
return ImageCache.load(path, pack);
|
||||
return ImageCache.load(path, pack, files);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
+5
-2
@@ -11,10 +11,12 @@ 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;
|
||||
@@ -26,7 +28,8 @@ public class StitchedImageTemplate implements ObjectTemplate<Image>, ValidatedCo
|
||||
@Default
|
||||
private boolean zeroIndexed = false;
|
||||
|
||||
public StitchedImageTemplate(ConfigPack pack) {
|
||||
public StitchedImageTemplate(Loader files, ConfigPack pack) {
|
||||
this.files = files;
|
||||
this.pack = pack;
|
||||
}
|
||||
|
||||
@@ -36,7 +39,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);
|
||||
grid[i][j] = ImageCache.load(getFormattedPath(i, j), pack, files);
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.addons.palette.shortcut.block;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.structure.Structure;
|
||||
@@ -17,7 +17,7 @@ public class SingletonStructure implements Structure {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
world.setBlockState(location, blockState);
|
||||
return true;
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,7 +9,7 @@ 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.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class MutatedStructure implements Structure, Keyed<MutatedStructure> {
|
||||
@@ -32,7 +32,7 @@ public class MutatedStructure implements Structure, Keyed<MutatedStructure> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
return base.generate(location,
|
||||
world
|
||||
.buffer()
|
||||
|
||||
+7
-16
@@ -16,7 +16,6 @@ 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;
|
||||
@@ -30,7 +29,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.FileUtil;
|
||||
import com.dfsek.terra.api.util.StringUtil;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
|
||||
|
||||
@@ -59,21 +58,13 @@ public class SpongeSchematicAddon implements AddonInitializer {
|
||||
.register(addon, ConfigPackPreLoadEvent.class)
|
||||
.then(event -> {
|
||||
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
|
||||
try {
|
||||
FileUtil.filesWithExtension(event.getPack().getRootPath(), ".schem")
|
||||
.entrySet()
|
||||
event.getPack()
|
||||
.getLoader()
|
||||
.open("", ".schem")
|
||||
.thenEntries(entries -> entries
|
||||
.stream()
|
||||
.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);
|
||||
}
|
||||
.map(entry -> convert(entry.getValue(), StringUtil.fileName(entry.getKey())))
|
||||
.forEach(structureRegistry::register)).close();
|
||||
})
|
||||
.failThrough();
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,7 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.addons.sponge;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.block.state.BlockState;
|
||||
import com.dfsek.terra.api.registry.key.Keyed;
|
||||
@@ -36,7 +36,7 @@ public class SpongeStructure implements Structure, Keyed<SpongeStructure> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
int bX = location.getX();
|
||||
int bY = location.getY();
|
||||
int bZ = location.getZ();
|
||||
|
||||
+21
-26
@@ -7,9 +7,6 @@
|
||||
|
||||
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;
|
||||
@@ -22,7 +19,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.FileUtil;
|
||||
import com.dfsek.terra.api.util.StringUtil;
|
||||
|
||||
|
||||
public class TerraScriptAddon implements AddonInitializer {
|
||||
@@ -40,28 +37,26 @@ public class TerraScriptAddon implements AddonInitializer {
|
||||
.then(event -> {
|
||||
CheckedRegistry<Structure> structureRegistry = event.getPack().getOrCreateRegistry(Structure.class);
|
||||
CheckedRegistry<LootTable> lootRegistry = event.getPack().getOrCreateRegistry(LootTable.class);
|
||||
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);
|
||||
}
|
||||
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();
|
||||
})
|
||||
.priority(100)
|
||||
.failThrough();
|
||||
|
||||
+3
-3
@@ -14,7 +14,7 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.terrascript.parser.Parser;
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.Executable;
|
||||
@@ -131,14 +131,14 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("try")
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) {
|
||||
platform.getProfiler().push(profile);
|
||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0));
|
||||
platform.getProfiler().pop(profile);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation, int recursions) {
|
||||
public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation, int recursions) {
|
||||
platform.getProfiler().push(profile);
|
||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions));
|
||||
platform.getProfiler().pop(profile);
|
||||
|
||||
+4
-4
@@ -9,7 +9,7 @@ package com.dfsek.terra.addons.terrascript.script;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
@@ -20,14 +20,14 @@ import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
public class TerraImplementationArguments implements ImplementationArguments {
|
||||
private final Rotation rotation;
|
||||
private final RandomGenerator random;
|
||||
private final Random random;
|
||||
private final WritableWorld world;
|
||||
private final Map<Vector3, String> marks = new HashMap<>();
|
||||
private final int recursions;
|
||||
private final Vector3Int origin;
|
||||
private boolean waterlog = false;
|
||||
|
||||
public TerraImplementationArguments(Vector3Int origin, Rotation rotation, RandomGenerator random, WritableWorld world, int recursions) {
|
||||
public TerraImplementationArguments(Vector3Int origin, Rotation rotation, Random random, WritableWorld world, int recursions) {
|
||||
this.rotation = rotation;
|
||||
this.random = random;
|
||||
this.world = world;
|
||||
@@ -39,7 +39,7 @@ public class TerraImplementationArguments implements ImplementationArguments {
|
||||
return recursions;
|
||||
}
|
||||
|
||||
public RandomGenerator getRandom() {
|
||||
public Random getRandom() {
|
||||
return random;
|
||||
}
|
||||
|
||||
|
||||
+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
-4
@@ -10,8 +10,7 @@ package com.dfsek.terra.addons.terrascript.script.functions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.random.RandomGeneratorFactory;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
|
||||
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
|
||||
@@ -85,8 +84,7 @@ public class LootFunction implements Function<Void> {
|
||||
if(event.isCancelled()) return;
|
||||
|
||||
event.getTable().fillInventory(container.getInventory(),
|
||||
RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of(
|
||||
"Xoroshiro128PlusPlus").create(apply.hashCode()));
|
||||
new Random(apply.hashCode()));
|
||||
data.update(false);
|
||||
} catch(Exception e) {
|
||||
LOGGER.error("Could not apply loot at {}", apply, e);
|
||||
|
||||
@@ -2,7 +2,7 @@ dependencies {
|
||||
api("ca.solo-studios", "strata", Versions.Libraries.strata)
|
||||
compileOnlyApi("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
testImplementation("org.slf4j", "slf4j-api", Versions.Libraries.slf4j)
|
||||
api("cloud.commandframework", "cloud-core", Versions.Libraries.cloud)
|
||||
api("org.incendo", "cloud-core", Versions.Libraries.cloud)
|
||||
|
||||
api("com.dfsek.tectonic", "common", Versions.Libraries.tectonic)
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import java.io.File;
|
||||
|
||||
import com.dfsek.terra.api.addon.BaseAddon;
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.config.MetaPack;
|
||||
import com.dfsek.terra.api.config.PluginConfig;
|
||||
import com.dfsek.terra.api.event.EventManager;
|
||||
import com.dfsek.terra.api.handle.ItemHandle;
|
||||
@@ -62,10 +61,6 @@ public interface Platform extends LoaderRegistrar {
|
||||
@Contract(pure = true)
|
||||
CheckedRegistry<ConfigPack> getConfigRegistry();
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
CheckedRegistry<MetaPack> getMetaConfigRegistry();
|
||||
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
Registry<BaseAddon> getAddons();
|
||||
@@ -86,4 +81,7 @@ public interface Platform extends LoaderRegistrar {
|
||||
@NotNull
|
||||
@Contract(pure = true)
|
||||
Profiler getProfiler();
|
||||
|
||||
@Contract(pure = true)
|
||||
int getGenerationThreads();
|
||||
}
|
||||
|
||||
+50
-70
@@ -1,18 +1,19 @@
|
||||
package com.dfsek.terra.api.command.arguments;
|
||||
|
||||
import cloud.commandframework.ArgumentDescription;
|
||||
import cloud.commandframework.arguments.CommandArgument;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParseResult;
|
||||
import cloud.commandframework.arguments.parser.ArgumentParser;
|
||||
import cloud.commandframework.context.CommandContext;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.incendo.cloud.component.CommandComponent;
|
||||
import org.incendo.cloud.component.DefaultValue;
|
||||
import org.incendo.cloud.context.CommandContext;
|
||||
import org.incendo.cloud.context.CommandInput;
|
||||
import org.incendo.cloud.parser.ArgumentParseResult;
|
||||
import org.incendo.cloud.parser.ArgumentParser;
|
||||
import org.incendo.cloud.parser.ParserDescriptor;
|
||||
import org.incendo.cloud.suggestion.Suggestion;
|
||||
import org.incendo.cloud.suggestion.SuggestionProvider;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Queue;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -22,39 +23,22 @@ import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||
|
||||
|
||||
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 class RegistryArgument {
|
||||
|
||||
public static <T, R> Builder<T, R> builder(String name, Registry<R> registry) {
|
||||
return new Builder<>(name, registry);
|
||||
}
|
||||
|
||||
public static <T, R> CommandArgument<T, R> of(String name, Registry<R> registry) {
|
||||
public static <T, R> CommandComponent<T> of(String name, Registry<R> registry) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).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) {
|
||||
return RegistryArgument.<T, R>builder(name, registry).optional().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();
|
||||
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();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -63,49 +47,36 @@ public class RegistryArgument<T, R> extends CommandArgument<T, R> {
|
||||
return new Builder<>(name, registryFunction, (TypeToken<R>) TypeToken.get(registryType.getType()));
|
||||
}
|
||||
|
||||
public static <T, R> CommandArgument<T, R> of(String name, Function<CommandContext<T>, Registry<R>> registryFunction,
|
||||
TypeKey<R> registryType) {
|
||||
public static <T, R> CommandComponent<T> 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> 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) {
|
||||
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, String defaultKey) {
|
||||
return RegistryArgument.builder(name, registryFunction, registryType).asOptionalWithDefault(defaultKey).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 final class Builder<T, R> extends CommandArgument.Builder<T, R> {
|
||||
private final Function<CommandContext<T>, Registry<R>> registryFunction;
|
||||
private final TypeToken<R> typeToken;
|
||||
public static final class Builder<T, R> extends CommandComponent.Builder<T, R> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Builder(@NonNull String name, Registry<R> registry) {
|
||||
super((TypeToken<R>) TypeToken.get(registry.getType().getType()), name);
|
||||
this.registryFunction = commandContext -> registry;
|
||||
this.typeToken = (TypeToken<R>) TypeToken.get(registry.getType().getType());
|
||||
super();
|
||||
this.name(name);
|
||||
this.parser(ParserDescriptor.of(
|
||||
new RegistryArgumentParser<>(commandContext -> registry),
|
||||
(TypeToken<R>) TypeToken.get(registry.getType().getType())));
|
||||
}
|
||||
|
||||
private Builder(@NonNull String name, Function<CommandContext<T>, Registry<R>> registryFunction, TypeToken<R> 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()
|
||||
);
|
||||
super();
|
||||
this.name(name);
|
||||
this.parser(ParserDescriptor.of(new RegistryArgumentParser<>(registryFunction), typeToken));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,12 +90,12 @@ public class RegistryArgument<T, R> extends CommandArgument<T, R> {
|
||||
|
||||
@Override
|
||||
public @NonNull ArgumentParseResult<@NonNull R> parse(@NonNull CommandContext<@NonNull T> commandContext,
|
||||
@NonNull Queue<@NonNull String> inputQueue) {
|
||||
String input = inputQueue.remove();
|
||||
String next = inputQueue.peek();
|
||||
if(next != null && next.equals(":")) {
|
||||
input += inputQueue.remove();
|
||||
input += inputQueue.remove();
|
||||
@NonNull CommandInput commandInput) {
|
||||
String input = commandInput.readString();
|
||||
String next = commandInput.peekString();
|
||||
if(next.equals(":")) {
|
||||
input += commandInput.readString();
|
||||
input += commandInput.readString();
|
||||
}
|
||||
|
||||
Registry<R> registry = registryFunction.apply(commandContext);
|
||||
@@ -146,8 +117,17 @@ public class RegistryArgument<T, R> extends CommandArgument<T, R> {
|
||||
}
|
||||
|
||||
@Override
|
||||
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());
|
||||
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()));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ 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;
|
||||
|
||||
@@ -44,7 +43,7 @@ public interface ConfigPack extends LoaderRegistrar,
|
||||
|
||||
List<GenerationStage> getStages();
|
||||
|
||||
Path getRootPath();
|
||||
Loader getLoader();
|
||||
|
||||
String getAuthor();
|
||||
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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,27 +0,0 @@
|
||||
package com.dfsek.terra.api.config;
|
||||
|
||||
import ca.solostudios.strata.version.Version;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.dfsek.terra.api.properties.PropertyHolder;
|
||||
import com.dfsek.terra.api.registry.key.Keyed;
|
||||
import com.dfsek.terra.api.registry.meta.CheckedRegistryHolder;
|
||||
import com.dfsek.terra.api.registry.meta.RegistryProvider;
|
||||
import com.dfsek.terra.api.tectonic.ConfigLoadingDelegate;
|
||||
import com.dfsek.terra.api.tectonic.LoaderRegistrar;
|
||||
|
||||
|
||||
public interface MetaPack extends LoaderRegistrar,
|
||||
ConfigLoadingDelegate,
|
||||
CheckedRegistryHolder,
|
||||
RegistryProvider,
|
||||
Keyed<MetaPack>,
|
||||
PropertyHolder {
|
||||
|
||||
Map<String, ConfigPack> packs();
|
||||
|
||||
String getAuthor();
|
||||
|
||||
Version getVersion();
|
||||
}
|
||||
+8
-1
@@ -12,6 +12,7 @@ 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;
|
||||
|
||||
@@ -24,11 +25,13 @@ 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, BiConsumer<String, Configuration> consumer) {
|
||||
public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, BiConsumer<String, Configuration> consumer) {
|
||||
this.pack = pack;
|
||||
this.loader = loader;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
@@ -40,4 +43,8 @@ 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;
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
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);
|
||||
}
|
||||
@@ -10,7 +10,7 @@ package com.dfsek.terra.api.structure;
|
||||
import org.jetbrains.annotations.ApiStatus.Experimental;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.inventory.Inventory;
|
||||
import com.dfsek.terra.api.inventory.ItemStack;
|
||||
@@ -22,16 +22,16 @@ public interface LootTable {
|
||||
* Fills an Inventory with loot.
|
||||
*
|
||||
* @param i The Inventory to fill.
|
||||
* @param r The The RandomGenerator instance to use.
|
||||
* @param r The The Random instance to use.
|
||||
*/
|
||||
void fillInventory(Inventory i, RandomGenerator r);
|
||||
void fillInventory(Inventory i, Random r);
|
||||
|
||||
/**
|
||||
* Fetches a list of ItemStacks from the loot table using the given RandomGenerator instance.
|
||||
* Fetches a list of ItemStacks from the loot table using the given Random instance.
|
||||
*
|
||||
* @param r The RandomGenerator instance to use.
|
||||
* @param r The Random instance to use.
|
||||
*
|
||||
* @return List<ItemStack> - The list of loot fetched.
|
||||
*/
|
||||
List<ItemStack> getLoot(RandomGenerator r);
|
||||
List<ItemStack> getLoot(Random r);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
package com.dfsek.terra.api.structure;
|
||||
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
import com.dfsek.terra.api.util.Rotation;
|
||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||
@@ -15,5 +15,5 @@ import com.dfsek.terra.api.world.WritableWorld;
|
||||
|
||||
|
||||
public interface Structure {
|
||||
boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation);
|
||||
boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ package com.dfsek.terra.api.util;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.random.RandomGenerator;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
public class ConstantRange implements Range {
|
||||
@@ -36,7 +36,7 @@ public class ConstantRange implements Range {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get(RandomGenerator r) {
|
||||
public int get(Random r) {
|
||||
return r.nextInt(min, max);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user