mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 14:50:56 +00:00
terraScript random is no more
This commit is contained in:
+6
-16
@@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for bilinear interpolation of values arranged on a unit square.
|
* Class for bilinear interpolation of values arranged on a unit square.
|
||||||
*/
|
*/
|
||||||
@@ -28,19 +31,6 @@ public class Interpolator {
|
|||||||
this.v3 = v3;
|
this.v3 = v3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 1D Linear interpolation between 2 points 1 unit apart.
|
|
||||||
*
|
|
||||||
* @param t - Distance from v0. Total distance between v0 and v1 is 1 unit.
|
|
||||||
* @param v0 - Value at v0.
|
|
||||||
* @param v1 - Value at v1.
|
|
||||||
*
|
|
||||||
* @return double - The interpolated value.
|
|
||||||
*/
|
|
||||||
public static double lerp(double t, double v0, double v1) {
|
|
||||||
return v0 + t * (v1 - v0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D Bilinear interpolation between 4 points on a unit square.
|
* 2D Bilinear interpolation between 4 points on a unit square.
|
||||||
*
|
*
|
||||||
@@ -50,8 +40,8 @@ public class Interpolator {
|
|||||||
* @return double - The interpolated value.
|
* @return double - The interpolated value.
|
||||||
*/
|
*/
|
||||||
public double bilerp(double s, double t) {
|
public double bilerp(double s, double t) {
|
||||||
double v01 = lerp(s, v0, v1);
|
double v01 = MathUtil.lerp(s, v0, v1);
|
||||||
double v23 = lerp(s, v2, v3);
|
double v23 = MathUtil.lerp(s, v2, v3);
|
||||||
return lerp(t, v01, v23);
|
return MathUtil.lerp(t, v01, v23);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-1
@@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for bilinear interpolation of values arranged on a unit square.
|
* Class for bilinear interpolation of values arranged on a unit square.
|
||||||
*/
|
*/
|
||||||
@@ -34,6 +37,6 @@ public class Interpolator3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public double trilerp(double x, double y, double z) {
|
public double trilerp(double x, double y, double z) {
|
||||||
return Interpolator.lerp(x, top.bilerp(y, z), bottom.bilerp(y, z));
|
return MathUtil.lerp(x, top.bilerp(y, z), bottom.bilerp(y, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-9
@@ -1,13 +1,13 @@
|
|||||||
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties;
|
||||||
import com.dfsek.terra.api.properties.PropertyKey;
|
import com.dfsek.terra.api.properties.PropertyKey;
|
||||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||||
|
|
||||||
import static com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.Interpolator.lerp;
|
|
||||||
|
|
||||||
|
|
||||||
public class LazilyEvaluatedInterpolator {
|
public class LazilyEvaluatedInterpolator {
|
||||||
private final Double[] samples; //
|
private final Double[] samples; //
|
||||||
@@ -84,10 +84,10 @@ public class LazilyEvaluatedInterpolator {
|
|||||||
|
|
||||||
double xFrac = (double) (x % horizontalRes) / horizontalRes;
|
double xFrac = (double) (x % horizontalRes) / horizontalRes;
|
||||||
double zFrac = (double) (z % horizontalRes) / horizontalRes;
|
double zFrac = (double) (z % horizontalRes) / horizontalRes;
|
||||||
double lerp_bottom_0 = lerp(zFrac, sample_0_0_0, sample_0_0_1);
|
double lerp_bottom_0 = MathUtil.lerp(zFrac, sample_0_0_0, sample_0_0_1);
|
||||||
double lerp_bottom_1 = lerp(zFrac, sample_1_0_0, sample_1_0_1);
|
double lerp_bottom_1 = MathUtil.lerp(zFrac, sample_1_0_0, sample_1_0_1);
|
||||||
|
|
||||||
double lerp_bottom = lerp(xFrac, lerp_bottom_0, lerp_bottom_1);
|
double lerp_bottom = MathUtil.lerp(xFrac, lerp_bottom_0, lerp_bottom_1);
|
||||||
|
|
||||||
if(yRange) { // we can do bilerp
|
if(yRange) { // we can do bilerp
|
||||||
return lerp_bottom;
|
return lerp_bottom;
|
||||||
@@ -103,11 +103,11 @@ public class LazilyEvaluatedInterpolator {
|
|||||||
double sample_1_1_0 = sample(xIndex + 1, yIndex + 1, zIndex, x + horizontalRes, y + verticalRes, z);
|
double sample_1_1_0 = sample(xIndex + 1, yIndex + 1, zIndex, x + horizontalRes, y + verticalRes, z);
|
||||||
double sample_1_1_1 = sample(xIndex + 1, yIndex + 1, zIndex + 1, x + horizontalRes, y + verticalRes, z + horizontalRes);
|
double sample_1_1_1 = sample(xIndex + 1, yIndex + 1, zIndex + 1, x + horizontalRes, y + verticalRes, z + horizontalRes);
|
||||||
|
|
||||||
double lerp_top_0 = lerp(zFrac, sample_0_1_0, sample_0_1_1);
|
double lerp_top_0 = MathUtil.lerp(zFrac, sample_0_1_0, sample_0_1_1);
|
||||||
double lerp_top_1 = lerp(zFrac, sample_1_1_0, sample_1_1_1);
|
double lerp_top_1 = MathUtil.lerp(zFrac, sample_1_1_0, sample_1_1_1);
|
||||||
|
|
||||||
double lerp_top = lerp(xFrac, lerp_top_0, lerp_top_1);
|
double lerp_top = MathUtil.lerp(xFrac, lerp_top_0, lerp_top_1);
|
||||||
|
|
||||||
return lerp(yFrac, lerp_bottom, lerp_top);
|
return MathUtil.lerp(yFrac, lerp_bottom, lerp_top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-14
@@ -6,27 +6,24 @@ import cloud.commandframework.arguments.standard.EnumArgument;
|
|||||||
import cloud.commandframework.arguments.standard.LongArgument;
|
import cloud.commandframework.arguments.standard.LongArgument;
|
||||||
import cloud.commandframework.context.CommandContext;
|
import cloud.commandframework.context.CommandContext;
|
||||||
|
|
||||||
|
import java.util.random.RandomGenerator;
|
||||||
|
import java.util.random.RandomGeneratorFactory;
|
||||||
|
|
||||||
import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer;
|
import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer;
|
||||||
import com.dfsek.terra.addons.manifest.api.monad.Do;
|
import com.dfsek.terra.addons.manifest.api.monad.Do;
|
||||||
import com.dfsek.terra.addons.manifest.api.monad.Get;
|
import com.dfsek.terra.addons.manifest.api.monad.Get;
|
||||||
import com.dfsek.terra.addons.manifest.api.monad.Init;
|
import com.dfsek.terra.addons.manifest.api.monad.Init;
|
||||||
import com.dfsek.terra.api.Platform;
|
|
||||||
import com.dfsek.terra.api.addon.BaseAddon;
|
|
||||||
import com.dfsek.terra.api.command.CommandSender;
|
import com.dfsek.terra.api.command.CommandSender;
|
||||||
import com.dfsek.terra.api.command.arguments.RegistryArgument;
|
import com.dfsek.terra.api.command.arguments.RegistryArgument;
|
||||||
import com.dfsek.terra.api.entity.Entity;
|
import com.dfsek.terra.api.entity.Entity;
|
||||||
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
|
|
||||||
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
|
import com.dfsek.terra.api.event.events.platform.CommandRegistrationEvent;
|
||||||
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
|
||||||
import com.dfsek.terra.api.inject.annotations.Inject;
|
|
||||||
import com.dfsek.terra.api.registry.Registry;
|
import com.dfsek.terra.api.registry.Registry;
|
||||||
import com.dfsek.terra.api.structure.Structure;
|
import com.dfsek.terra.api.structure.Structure;
|
||||||
import com.dfsek.terra.api.util.Rotation;
|
import com.dfsek.terra.api.util.Rotation;
|
||||||
import com.dfsek.terra.api.util.function.monad.Monad;
|
import com.dfsek.terra.api.util.function.monad.Monad;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
|
||||||
import java.util.random.RandomGenerator;
|
|
||||||
import java.util.random.RandomGeneratorFactory;
|
|
||||||
|
|
||||||
public class StructureCommandAddon implements MonadAddonInitializer {
|
public class StructureCommandAddon implements MonadAddonInitializer {
|
||||||
private static Registry<Structure> getStructureRegistry(CommandContext<CommandSender> sender) {
|
private static Registry<Structure> getStructureRegistry(CommandContext<CommandSender> sender) {
|
||||||
@@ -42,7 +39,7 @@ public class StructureCommandAddon implements MonadAddonInitializer {
|
|||||||
handler.register(base, CommandRegistrationEvent.class)
|
handler.register(base, CommandRegistrationEvent.class)
|
||||||
.then(event -> {
|
.then(event -> {
|
||||||
CommandManager<CommandSender> manager = event.getCommandManager();
|
CommandManager<CommandSender> manager = event.getCommandManager();
|
||||||
|
|
||||||
manager.command(
|
manager.command(
|
||||||
manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures"))
|
manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures"))
|
||||||
.literal("generate")
|
.literal("generate")
|
||||||
@@ -57,13 +54,8 @@ public class StructureCommandAddon implements MonadAddonInitializer {
|
|||||||
structure.generate(
|
structure.generate(
|
||||||
sender.position().toInt(),
|
sender.position().toInt(),
|
||||||
sender.world(),
|
sender.world(),
|
||||||
((Long) context.get("seed") == 0)
|
context.get("rotation"), sender.world().getSeed()
|
||||||
? RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
);
|
||||||
.create()
|
|
||||||
: RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
|
||||||
.create(context.get("seed")),
|
|
||||||
context.get("rotation")
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.permission("terra.structures.generate")
|
.permission("terra.structures.generate")
|
||||||
);
|
);
|
||||||
|
|||||||
+3
-8
@@ -74,7 +74,7 @@ public class TerraFlora implements Structure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed) {
|
||||||
boolean doRotation = testRotation.size() > 0;
|
boolean doRotation = testRotation.size() > 0;
|
||||||
int size = layers.size();
|
int size = layers.size();
|
||||||
int c = ceiling ? -1 : 1;
|
int c = ceiling ? -1 : 1;
|
||||||
@@ -86,13 +86,8 @@ public class TerraFlora implements Structure {
|
|||||||
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
|
||||||
int lvl = (FastMath.abs(i));
|
int lvl = (FastMath.abs(i));
|
||||||
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(),
|
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(),
|
||||||
location.getZ(), world.getSeed());
|
location.getZ(), seed);
|
||||||
if(doRotation) {
|
|
||||||
Direction oneFace = new ArrayList<>(faces).get(
|
|
||||||
RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of("Xoroshiro128PlusPlus")
|
|
||||||
.create(location.getX() ^ location.getZ())
|
|
||||||
.nextInt(faces.size())); // Get RandomGenerator face.
|
|
||||||
}
|
|
||||||
world.setBlockState(location.mutable().add(0, i + c, 0).immutable(), data, physics);
|
world.setBlockState(location.mutable().add(0, i + c, 0).immutable(), data, physics);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ dependencies {
|
|||||||
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
compileOnlyApi(project(":common:addons:manifest-addon-loader"))
|
||||||
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama)
|
||||||
|
compileOnlyApi(project(":common:addons:config-noise-function"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.ore;
|
package com.dfsek.terra.addons.ore;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
|
||||||
import com.dfsek.terra.addons.ore.ores.VanillaOre;
|
import com.dfsek.terra.addons.ore.ores.VanillaOre;
|
||||||
import com.dfsek.terra.api.Platform;
|
import com.dfsek.terra.api.Platform;
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
@@ -19,6 +20,6 @@ public class OreFactory implements ConfigFactory<OreTemplate, Structure> {
|
|||||||
public VanillaOre build(OreTemplate config, Platform platform) {
|
public VanillaOre build(OreTemplate config, Platform platform) {
|
||||||
BlockState m = config.getMaterial();
|
BlockState m = config.getMaterial();
|
||||||
return new VanillaOre(m, config.getSize(), config.getReplaceable(), config.doPhysics(), config.isExposed(),
|
return new VanillaOre(m, config.getSize(), config.getReplaceable(), config.doPhysics(), config.isExposed(),
|
||||||
config.getMaterialOverrides());
|
config.getMaterialOverrides(), new WhiteNoiseSampler());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-8
@@ -7,10 +7,13 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.addons.ore.ores;
|
package com.dfsek.terra.addons.ore.ores;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.MathUtil;
|
||||||
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.random.RandomGenerator;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.block.BlockType;
|
import com.dfsek.terra.api.block.BlockType;
|
||||||
import com.dfsek.terra.api.block.state.BlockState;
|
import com.dfsek.terra.api.block.state.BlockState;
|
||||||
@@ -30,38 +33,40 @@ public class VanillaOre implements Structure {
|
|||||||
private final boolean applyGravity;
|
private final boolean applyGravity;
|
||||||
private final double exposed;
|
private final double exposed;
|
||||||
private final Map<BlockType, BlockState> materials;
|
private final Map<BlockType, BlockState> materials;
|
||||||
|
private final NoiseSampler sampler;
|
||||||
|
|
||||||
public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity,
|
public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity,
|
||||||
double exposed, Map<BlockType, BlockState> materials) {
|
double exposed, Map<BlockType, BlockState> materials, NoiseSampler sampler) {
|
||||||
this.material = material;
|
this.material = material;
|
||||||
this.size = size;
|
this.size = size;
|
||||||
this.replaceable = replaceable;
|
this.replaceable = replaceable;
|
||||||
this.applyGravity = applyGravity;
|
this.applyGravity = applyGravity;
|
||||||
this.exposed = exposed;
|
this.exposed = exposed;
|
||||||
this.materials = materials;
|
this.materials = materials;
|
||||||
|
this.sampler = sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed){
|
||||||
int centerX = location.getX();
|
int centerX = location.getX();
|
||||||
int centerZ = location.getZ();
|
int centerZ = location.getZ();
|
||||||
int centerY = location.getY();
|
int centerY = location.getY();
|
||||||
|
|
||||||
|
|
||||||
float f = random.nextFloat() * (float) Math.PI;
|
double f = sampler.noise(centerX, centerY, centerZ, seed) * (float) Math.PI;
|
||||||
|
|
||||||
double d1 = centerX + 8 + FastMath.sin(f) * size / 8.0F;
|
double d1 = centerX + 8 + FastMath.sin(f) * size / 8.0F;
|
||||||
double d2 = centerX + 8 - FastMath.sin(f) * size / 8.0F;
|
double d2 = centerX + 8 - FastMath.sin(f) * size / 8.0F;
|
||||||
double d3 = centerZ + 8 + FastMath.cos(f) * size / 8.0F;
|
double d3 = centerZ + 8 + FastMath.cos(f) * size / 8.0F;
|
||||||
double d4 = centerZ + 8 - FastMath.cos(f) * size / 8.0F;
|
double d4 = centerZ + 8 - FastMath.cos(f) * size / 8.0F;
|
||||||
|
|
||||||
double d5 = centerY + random.nextInt(3) - 2D;
|
double d5 = centerY + (Math.round(sampler.noise(centerX, centerY, centerZ, seed + 1) + 1)) - 2D;
|
||||||
double d6 = centerY + random.nextInt(3) - 2D;
|
double d6 = centerY + (Math.round(sampler.noise(centerX, centerY, centerZ, seed + 2) + 1)) - 2D;
|
||||||
|
|
||||||
for(int i = 0; i < size; i++) {
|
for(int i = 0; i < size; i++) {
|
||||||
float iFactor = (float) i / (float) size;
|
float iFactor = (float) i / (float) size;
|
||||||
|
|
||||||
double d10 = random.nextDouble() * size / 16.0D;
|
double d10 = MathUtil.inverseLerp(sampler.noise(centerX, centerY, centerZ, seed + 2 + (i * 2 - 1)), -1, 1) * size / 16.0D;
|
||||||
double d11 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
|
double d11 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
|
||||||
double d12 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
|
double d12 = (FastMath.sin(Math.PI * iFactor) + 1.0) * d10 + 1.0;
|
||||||
|
|
||||||
@@ -85,7 +90,7 @@ public class VanillaOre implements Structure {
|
|||||||
if(y >= world.getMaxHeight() || y < world.getMinHeight()) continue;
|
if(y >= world.getMaxHeight() || y < world.getMinHeight()) continue;
|
||||||
BlockType block = world.getBlockState(x, y, z).getBlockType();
|
BlockType block = world.getBlockState(x, y, z).getBlockType();
|
||||||
if((d13 * d13 + d14 * d14 + d15 * d15 < 1.0D) && getReplaceable().contains(block)) {
|
if((d13 * d13 + d14 * d14 + d15 * d15 < 1.0D) && getReplaceable().contains(block)) {
|
||||||
if(exposed > random.nextDouble() || !(world.getBlockState(x, y, z - 1).isAir() ||
|
if(exposed > MathUtil.inverseLerp(sampler.noise(centerX, centerY, centerZ, seed + 2 + (i * 2)), -1, 1) || !(world.getBlockState(x, y, z - 1).isAir() ||
|
||||||
world.getBlockState(x, y, z + 1).isAir() ||
|
world.getBlockState(x, y, z + 1).isAir() ||
|
||||||
world.getBlockState(x, y - 1, z).isAir() ||
|
world.getBlockState(x, y - 1, z).isAir() ||
|
||||||
world.getBlockState(x, y + 1, z).isAir() ||
|
world.getBlockState(x, y + 1, z).isAir() ||
|
||||||
|
|||||||
@@ -9,4 +9,6 @@ website:
|
|||||||
issues: https://github.com/PolyhedralDev/Terra/issues
|
issues: https://github.com/PolyhedralDev/Terra/issues
|
||||||
source: https://github.com/PolyhedralDev/Terra
|
source: https://github.com/PolyhedralDev/Terra
|
||||||
docs: https://terra.polydev.org
|
docs: https://terra.polydev.org
|
||||||
license: MIT License
|
license: MIT License
|
||||||
|
depends:
|
||||||
|
config-noise-function: "1.+"
|
||||||
+2
-4
@@ -73,10 +73,8 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab
|
|||||||
.forEach(y -> feature.getStructure(world, x, y, z)
|
.forEach(y -> feature.getStructure(world, x, y, z)
|
||||||
.generate(Vector3Int.of(x, y, z),
|
.generate(Vector3Int.of(x, y, z),
|
||||||
world,
|
world,
|
||||||
RandomGeneratorFactory.<RandomGenerator.SplittableGenerator>of(
|
Rotation.NONE,
|
||||||
"Xoroshiro128PlusPlus")
|
coordinateSeed * 31 + y)
|
||||||
.create(coordinateSeed * 31 + y),
|
|
||||||
Rotation.NONE)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
platform.getProfiler().pop(feature.getID());
|
platform.getProfiler().pop(feature.getID());
|
||||||
|
|||||||
+1
-1
@@ -17,7 +17,7 @@ public class SingletonStructure implements Structure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed) {
|
||||||
world.setBlockState(location, blockState);
|
world.setBlockState(location, blockState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-3
@@ -32,13 +32,12 @@ public class MutatedStructure implements Structure, Keyed<MutatedStructure> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed) {
|
||||||
return base.generate(location,
|
return base.generate(location,
|
||||||
world
|
world
|
||||||
.buffer()
|
.buffer()
|
||||||
.read(readInterceptor)
|
.read(readInterceptor)
|
||||||
.write(writeInterceptor)
|
.write(writeInterceptor)
|
||||||
.build(),
|
.build(), rotation, seed);
|
||||||
random, rotation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ public class SpongeStructure implements Structure, Keyed<SpongeStructure> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed) {
|
||||||
int bX = location.getX();
|
int bX = location.getX();
|
||||||
int bY = location.getY();
|
int bY = location.getY();
|
||||||
int bZ = location.getZ();
|
int bZ = location.getZ();
|
||||||
|
|||||||
+4
-6
@@ -29,7 +29,6 @@ import com.dfsek.terra.addons.terrascript.script.builders.EntityFunctionBuilder;
|
|||||||
import com.dfsek.terra.addons.terrascript.script.builders.GetMarkFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.GetMarkFunctionBuilder;
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.LootFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.LootFunctionBuilder;
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.PullFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.PullFunctionBuilder;
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.RandomFunctionBuilder;
|
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.RecursionsFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.RecursionsFunctionBuilder;
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.SetMarkFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.SetMarkFunctionBuilder;
|
||||||
import com.dfsek.terra.addons.terrascript.script.builders.StateFunctionBuilder;
|
import com.dfsek.terra.addons.terrascript.script.builders.StateFunctionBuilder;
|
||||||
@@ -77,7 +76,6 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
|||||||
.registerFunction("block", new BlockFunctionBuilder(platform))
|
.registerFunction("block", new BlockFunctionBuilder(platform))
|
||||||
.registerFunction("debugBlock", new BlockFunctionBuilder(platform))
|
.registerFunction("debugBlock", new BlockFunctionBuilder(platform))
|
||||||
.registerFunction("structure", new StructureFunctionBuilder(registry, platform))
|
.registerFunction("structure", new StructureFunctionBuilder(registry, platform))
|
||||||
.registerFunction("randomInt", new RandomFunctionBuilder())
|
|
||||||
.registerFunction("recursions", new RecursionsFunctionBuilder())
|
.registerFunction("recursions", new RecursionsFunctionBuilder())
|
||||||
.registerFunction("setMark", new SetMarkFunctionBuilder())
|
.registerFunction("setMark", new SetMarkFunctionBuilder())
|
||||||
.registerFunction("getMark", new GetMarkFunctionBuilder())
|
.registerFunction("getMark", new GetMarkFunctionBuilder())
|
||||||
@@ -130,16 +128,16 @@ public class StructureScript implements Structure, Keyed<StructureScript> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("try")
|
@SuppressWarnings("try")
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long seed) {
|
||||||
platform.getProfiler().push(profile);
|
platform.getProfiler().push(profile);
|
||||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0));
|
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, world, 0));
|
||||||
platform.getProfiler().pop(profile);
|
platform.getProfiler().pop(profile);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation, int recursions) {
|
public boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, int recursions) {
|
||||||
platform.getProfiler().push(profile);
|
platform.getProfiler().push(profile);
|
||||||
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions));
|
boolean result = applyBlock(new TerraImplementationArguments(location, rotation, world, recursions));
|
||||||
platform.getProfiler().pop(profile);
|
platform.getProfiler().pop(profile);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-7
@@ -20,16 +20,14 @@ import com.dfsek.terra.api.world.WritableWorld;
|
|||||||
|
|
||||||
public class TerraImplementationArguments implements ImplementationArguments {
|
public class TerraImplementationArguments implements ImplementationArguments {
|
||||||
private final Rotation rotation;
|
private final Rotation rotation;
|
||||||
private final RandomGenerator random;
|
|
||||||
private final WritableWorld world;
|
private final WritableWorld world;
|
||||||
private final Map<Vector3, String> marks = new HashMap<>();
|
private final Map<Vector3, String> marks = new HashMap<>();
|
||||||
private final int recursions;
|
private final int recursions;
|
||||||
private final Vector3Int origin;
|
private final Vector3Int origin;
|
||||||
private boolean waterlog = false;
|
private boolean waterlog = false;
|
||||||
|
|
||||||
public TerraImplementationArguments(Vector3Int origin, Rotation rotation, RandomGenerator random, WritableWorld world, int recursions) {
|
public TerraImplementationArguments(Vector3Int origin, Rotation rotation, WritableWorld world, int recursions) {
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
this.random = random;
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.recursions = recursions;
|
this.recursions = recursions;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
@@ -39,10 +37,6 @@ public class TerraImplementationArguments implements ImplementationArguments {
|
|||||||
return recursions;
|
return recursions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RandomGenerator getRandom() {
|
|
||||||
return random;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Rotation getRotation() {
|
public Rotation getRotation() {
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Polyhedral Development
|
|
||||||
*
|
|
||||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
|
||||||
* reference the LICENSE file in this module's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.addons.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.RandomFunction;
|
|
||||||
import com.dfsek.terra.addons.terrascript.tokenizer.Position;
|
|
||||||
|
|
||||||
|
|
||||||
public class RandomFunctionBuilder implements FunctionBuilder<RandomFunction> {
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public RandomFunction build(List<Returnable<?>> argumentList, Position position) {
|
|
||||||
return new RandomFunction((Returnable<Number>) argumentList.get(0), position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int argNumber() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Returnable.ReturnType getArgument(int position) {
|
|
||||||
if(position == 0) return Returnable.ReturnType.NUMBER;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-43
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020-2021 Polyhedral Development
|
|
||||||
*
|
|
||||||
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
|
||||||
* reference the LICENSE file in this module's root directory.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.dfsek.terra.addons.terrascript.script.functions;
|
|
||||||
|
|
||||||
import com.dfsek.terra.addons.terrascript.parser.lang.ImplementationArguments;
|
|
||||||
import com.dfsek.terra.addons.terrascript.parser.lang.Returnable;
|
|
||||||
import com.dfsek.terra.addons.terrascript.parser.lang.Scope;
|
|
||||||
import com.dfsek.terra.addons.terrascript.parser.lang.functions.Function;
|
|
||||||
import com.dfsek.terra.addons.terrascript.script.TerraImplementationArguments;
|
|
||||||
import com.dfsek.terra.addons.terrascript.tokenizer.Position;
|
|
||||||
|
|
||||||
|
|
||||||
public class RandomFunction implements Function<Integer> {
|
|
||||||
private final Returnable<Number> numberReturnable;
|
|
||||||
private final Position position;
|
|
||||||
|
|
||||||
public RandomFunction(Returnable<Number> numberReturnable, Position position) {
|
|
||||||
this.numberReturnable = numberReturnable;
|
|
||||||
this.position = position;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnType returnType() {
|
|
||||||
return ReturnType.NUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer apply(ImplementationArguments implementationArguments, Scope scope) {
|
|
||||||
return ((TerraImplementationArguments) implementationArguments).getRandom().nextInt(
|
|
||||||
numberReturnable.apply(implementationArguments, scope).intValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Position getPosition() {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+2
-13
@@ -67,31 +67,20 @@ public class StructureFunction implements Function<Boolean> {
|
|||||||
|
|
||||||
String app = id.apply(implementationArguments, scope);
|
String app = id.apply(implementationArguments, scope);
|
||||||
return registry.getByID(app).map(script -> {
|
return registry.getByID(app).map(script -> {
|
||||||
Rotation rotation1;
|
|
||||||
String rotString = rotations.get(arguments.getRandom().nextInt(rotations.size())).apply(implementationArguments, scope);
|
|
||||||
try {
|
|
||||||
rotation1 = Rotation.valueOf(rotString);
|
|
||||||
} catch(IllegalArgumentException e) {
|
|
||||||
LOGGER.warn("Invalid rotation {}", rotString);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(script instanceof StructureScript structureScript) {
|
if(script instanceof StructureScript structureScript) {
|
||||||
return structureScript.generate(arguments.getOrigin(),
|
return structureScript.generate(arguments.getOrigin(),
|
||||||
arguments.getWorld()
|
arguments.getWorld()
|
||||||
.buffer(FastMath.roundToInt(xz.getX()),
|
.buffer(FastMath.roundToInt(xz.getX()),
|
||||||
y.apply(implementationArguments, scope).intValue(),
|
y.apply(implementationArguments, scope).intValue(),
|
||||||
FastMath.roundToInt(xz.getZ())),
|
FastMath.roundToInt(xz.getZ())),
|
||||||
arguments.getRandom(),
|
arguments.getRotation(), arguments.getRecursions() + 1);
|
||||||
arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1);
|
|
||||||
}
|
}
|
||||||
return script.generate(arguments.getOrigin(),
|
return script.generate(arguments.getOrigin(),
|
||||||
arguments.getWorld()
|
arguments.getWorld()
|
||||||
.buffer(FastMath.roundToInt(xz.getX()),
|
.buffer(FastMath.roundToInt(xz.getX()),
|
||||||
y.apply(implementationArguments, scope).intValue(),
|
y.apply(implementationArguments, scope).intValue(),
|
||||||
FastMath.roundToInt(xz.getZ())),
|
FastMath.roundToInt(xz.getZ())),
|
||||||
arguments.getRandom(),
|
arguments.getRotation(), arguments.getWorld().getSeed());
|
||||||
arguments.getRotation().rotate(rotation1));
|
|
||||||
}).orElseGet(() -> {
|
}).orElseGet(() -> {
|
||||||
LOGGER.error("No such structure {}", app);
|
LOGGER.error("No such structure {}", app);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ package com.dfsek.terra.api.structure;
|
|||||||
|
|
||||||
import java.util.random.RandomGenerator;
|
import java.util.random.RandomGenerator;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
import com.dfsek.terra.api.util.Rotation;
|
import com.dfsek.terra.api.util.Rotation;
|
||||||
import com.dfsek.terra.api.util.vector.Vector3Int;
|
import com.dfsek.terra.api.util.vector.Vector3Int;
|
||||||
import com.dfsek.terra.api.world.WritableWorld;
|
import com.dfsek.terra.api.world.WritableWorld;
|
||||||
|
|
||||||
|
|
||||||
public interface Structure {
|
public interface Structure {
|
||||||
boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation);
|
boolean generate(Vector3Int location, WritableWorld world, Rotation rotation, Long Seed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,4 +173,21 @@ public final class MathUtil {
|
|||||||
|
|
||||||
return mu + sigma * val;
|
return mu + sigma * val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1D Linear interpolation between 2 points 1 unit apart.
|
||||||
|
*
|
||||||
|
* @param t - Distance from v0. Total distance between v0 and v1 is 1 unit.
|
||||||
|
* @param v0 - Value at v0.
|
||||||
|
* @param v1 - Value at v1.
|
||||||
|
*
|
||||||
|
* @return double - The interpolated value.
|
||||||
|
*/
|
||||||
|
public static double lerp(double t, double v0, double v1) {
|
||||||
|
return v0 + t * (v1 - v0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double inverseLerp(double t, double v0, double v1) {
|
||||||
|
return (t - v0) / (v1 - v0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -1,6 +1,8 @@
|
|||||||
package com.dfsek.terra.mod.mixin.gameplay;
|
package com.dfsek.terra.mod.mixin.gameplay;
|
||||||
|
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.world.World;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.ai.brain.task.BoneMealTask;
|
import net.minecraft.entity.ai.brain.task.BoneMealTask;
|
||||||
@@ -43,14 +45,13 @@ public class BoneMealTaskMixin {
|
|||||||
if(canGrow != null) {
|
if(canGrow != null) {
|
||||||
RandomGenerator random = MinecraftAdapter.adapt(world.getRandom());
|
RandomGenerator random = MinecraftAdapter.adapt(world.getRandom());
|
||||||
cir.setReturnValue(canGrow.generate(
|
cir.setReturnValue(canGrow.generate(
|
||||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE));
|
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, Rotation.NONE, world.getSeed() + random.nextLong(Long.MAX_VALUE)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cir.setReturnValue(true);
|
cir.setReturnValue(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cir.setReturnValue(false);
|
cir.setReturnValue(false);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public class FertilizableUtil {
|
|||||||
Structure canGrow = config.getCanGrow();
|
Structure canGrow = config.getCanGrow();
|
||||||
if(canGrow != null) {
|
if(canGrow != null) {
|
||||||
if(!canGrow.generate(
|
if(!canGrow.generate(
|
||||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE)) {
|
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, Rotation.NONE, world.getSeed() + random.nextLong(Long.MAX_VALUE))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ public class FertilizableUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.getStructures().get(random).generate(
|
config.getStructures().get(random).generate(
|
||||||
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, random, Rotation.NONE);
|
Vector3Int.of(pos.getX(), pos.getY(), pos.getZ()), (WritableWorld) world, Rotation.NONE, world.getSeed() + random.nextLong(Long.MAX_VALUE));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user