diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java index e96e15879..e30a70aae 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator.java @@ -7,6 +7,9 @@ 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. */ @@ -28,19 +31,6 @@ public class Interpolator { 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. * @@ -50,8 +40,8 @@ public class Interpolator { * @return double - The interpolated value. */ public double bilerp(double s, double t) { - double v01 = lerp(s, v0, v1); - double v23 = lerp(s, v2, v3); - return lerp(t, v01, v23); + double v01 = MathUtil.lerp(s, v0, v1); + double v23 = MathUtil.lerp(s, v2, v3); + return MathUtil.lerp(t, v01, v23); } } \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java index 804770b42..b313828d3 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/Interpolator3.java @@ -7,6 +7,9 @@ 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. */ @@ -34,6 +37,6 @@ public class Interpolator3 { } 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)); } } \ No newline at end of file diff --git a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java index f2a48c50a..ecc19d2f9 100644 --- a/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java +++ b/common/addons/chunk-generator-noise-3d/src/main/java/com/dfsek/terra/addons/chunkgenerator/generation/math/interpolation/LazilyEvaluatedInterpolator.java @@ -1,13 +1,13 @@ package com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation; +import com.dfsek.terra.api.util.MathUtil; + import net.jafama.FastMath; import com.dfsek.terra.addons.chunkgenerator.config.noise.BiomeNoiseProperties; import com.dfsek.terra.api.properties.PropertyKey; import com.dfsek.terra.api.world.biome.generation.BiomeProvider; -import static com.dfsek.terra.addons.chunkgenerator.generation.math.interpolation.Interpolator.lerp; - public class LazilyEvaluatedInterpolator { private final Double[] samples; // @@ -84,10 +84,10 @@ public class LazilyEvaluatedInterpolator { double xFrac = (double) (x % 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_1 = lerp(zFrac, sample_1_0_0, sample_1_0_1); + double lerp_bottom_0 = MathUtil.lerp(zFrac, sample_0_0_0, sample_0_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 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_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_1 = lerp(zFrac, sample_1_1_0, sample_1_1_1); + double lerp_top_0 = MathUtil.lerp(zFrac, sample_0_1_0, sample_0_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); } } diff --git a/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java b/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java index dbafef915..8b1dc67c9 100644 --- a/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java +++ b/common/addons/command-structures/src/main/java/com/dfsek/terra/addons/commands/structure/StructureCommandAddon.java @@ -6,27 +6,24 @@ import cloud.commandframework.arguments.standard.EnumArgument; import cloud.commandframework.arguments.standard.LongArgument; 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.monad.Do; import com.dfsek.terra.addons.manifest.api.monad.Get; 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.arguments.RegistryArgument; 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.functional.FunctionalEventHandler; -import com.dfsek.terra.api.inject.annotations.Inject; import com.dfsek.terra.api.registry.Registry; import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.Rotation; import com.dfsek.terra.api.util.function.monad.Monad; import com.dfsek.terra.api.util.reflection.TypeKey; -import java.util.random.RandomGenerator; -import java.util.random.RandomGeneratorFactory; public class StructureCommandAddon implements MonadAddonInitializer { private static Registry getStructureRegistry(CommandContext sender) { @@ -42,7 +39,7 @@ public class StructureCommandAddon implements MonadAddonInitializer { handler.register(base, CommandRegistrationEvent.class) .then(event -> { CommandManager manager = event.getCommandManager(); - + manager.command( manager.commandBuilder("structures", ArgumentDescription.of("Manage or generate structures")) .literal("generate") @@ -57,13 +54,8 @@ public class StructureCommandAddon implements MonadAddonInitializer { structure.generate( sender.position().toInt(), sender.world(), - ((Long) context.get("seed") == 0) - ? RandomGeneratorFactory.of("Xoroshiro128PlusPlus") - .create() - : RandomGeneratorFactory.of("Xoroshiro128PlusPlus") - .create(context.get("seed")), - context.get("rotation") - ); + context.get("rotation"), sender.world().getSeed() + ); }) .permission("terra.structures.generate") ); diff --git a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java index a28e2b05f..bbbd4fa3e 100644 --- a/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java +++ b/common/addons/config-flora/src/main/java/com/dfsek/terra/addons/flora/flora/gen/TerraFlora.java @@ -74,7 +74,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, Rotation rotation, Long seed) { boolean doRotation = testRotation.size() > 0; int size = layers.size(); 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 int lvl = (FastMath.abs(i)); BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(), - location.getZ(), world.getSeed()); - if(doRotation) { - Direction oneFace = new ArrayList<>(faces).get( - RandomGeneratorFactory.of("Xoroshiro128PlusPlus") - .create(location.getX() ^ location.getZ()) - .nextInt(faces.size())); // Get RandomGenerator face. - } + location.getZ(), seed); + world.setBlockState(location.mutable().add(0, i + c, 0).immutable(), data, physics); } return true; diff --git a/common/addons/config-ore/build.gradle.kts b/common/addons/config-ore/build.gradle.kts index d575f43d3..bd59de3b5 100644 --- a/common/addons/config-ore/build.gradle.kts +++ b/common/addons/config-ore/build.gradle.kts @@ -4,6 +4,7 @@ dependencies { compileOnlyApi(project(":common:addons:manifest-addon-loader")) implementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama) testImplementation("net.jafama", "jafama", Versions.Libraries.Internal.jafama) + compileOnlyApi(project(":common:addons:config-noise-function")) } tasks.named("shadowJar") { diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreFactory.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreFactory.java index 9d8b1055a..1d824a00a 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreFactory.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreFactory.java @@ -7,6 +7,7 @@ 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.api.Platform; import com.dfsek.terra.api.block.state.BlockState; @@ -19,6 +20,6 @@ public class OreFactory implements ConfigFactory { public VanillaOre build(OreTemplate config, Platform platform) { BlockState m = config.getMaterial(); return new VanillaOre(m, config.getSize(), config.getReplaceable(), config.doPhysics(), config.isExposed(), - config.getMaterialOverrides()); + config.getMaterialOverrides(), new WhiteNoiseSampler()); } } diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java index 7f3a781d7..02e98dd56 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/ores/VanillaOre.java @@ -7,10 +7,13 @@ 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 java.util.Map; -import java.util.random.RandomGenerator; import com.dfsek.terra.api.block.BlockType; import com.dfsek.terra.api.block.state.BlockState; @@ -30,38 +33,40 @@ public class VanillaOre implements Structure { private final boolean applyGravity; private final double exposed; private final Map materials; + private final NoiseSampler sampler; public VanillaOre(BlockState material, double size, MaterialSet replaceable, boolean applyGravity, - double exposed, Map materials) { + double exposed, Map materials, NoiseSampler sampler) { this.material = material; this.size = size; this.replaceable = replaceable; this.applyGravity = applyGravity; this.exposed = exposed; this.materials = materials; + this.sampler = sampler; } @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 centerZ = location.getZ(); 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 d2 = centerX + 8 - FastMath.sin(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 d5 = centerY + random.nextInt(3) - 2D; - double d6 = centerY + random.nextInt(3) - 2D; + double d5 = centerY + (Math.round(sampler.noise(centerX, centerY, centerZ, seed + 1) + 1)) - 2D; + double d6 = centerY + (Math.round(sampler.noise(centerX, centerY, centerZ, seed + 2) + 1)) - 2D; for(int i = 0; i < size; i++) { 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 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; BlockType block = world.getBlockState(x, y, z).getBlockType(); 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 - 1, z).isAir() || world.getBlockState(x, y + 1, z).isAir() || diff --git a/common/addons/config-ore/src/main/resources/terra.addon.yml b/common/addons/config-ore/src/main/resources/terra.addon.yml index 60ea05e60..d83bcb3cc 100644 --- a/common/addons/config-ore/src/main/resources/terra.addon.yml +++ b/common/addons/config-ore/src/main/resources/terra.addon.yml @@ -9,4 +9,6 @@ website: issues: https://github.com/PolyhedralDev/Terra/issues source: https://github.com/PolyhedralDev/Terra docs: https://terra.polydev.org -license: MIT License \ No newline at end of file +license: MIT License +depends: + config-noise-function: "1.+" \ No newline at end of file diff --git a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java index 150e381d4..6b300d778 100644 --- a/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java +++ b/common/addons/generation-stage-feature/src/main/java/com/dfsek/terra/addons/generation/feature/FeatureGenerationStage.java @@ -73,10 +73,8 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab .forEach(y -> feature.getStructure(world, x, y, z) .generate(Vector3Int.of(x, y, z), world, - RandomGeneratorFactory.of( - "Xoroshiro128PlusPlus") - .create(coordinateSeed * 31 + y), - Rotation.NONE) + Rotation.NONE, + coordinateSeed * 31 + y) ); } platform.getProfiler().pop(feature.getID()); diff --git a/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java b/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java index d7fba683f..831857c1f 100644 --- a/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java +++ b/common/addons/structure-block-shortcut/src/main/java/com/dfsek/terra/addons/palette/shortcut/block/SingletonStructure.java @@ -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, Rotation rotation, Long seed) { world.setBlockState(location, blockState); return true; } diff --git a/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java b/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java index 8ff16d9db..9b5bbb90c 100644 --- a/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java +++ b/common/addons/structure-mutator/src/main/java/com/dfsek/terra/addons/structure/mutator/MutatedStructure.java @@ -32,13 +32,12 @@ public class MutatedStructure implements Structure, Keyed { } @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, world .buffer() .read(readInterceptor) .write(writeInterceptor) - .build(), - random, rotation); + .build(), rotation, seed); } } diff --git a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java index 1e3cf7f0c..ef290b66c 100644 --- a/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java +++ b/common/addons/structure-sponge-loader/src/main/java/com/dfsek/terra/addons/sponge/SpongeStructure.java @@ -31,7 +31,7 @@ public class SpongeStructure implements Structure, Keyed { } @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 bY = location.getY(); int bZ = location.getZ(); diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java index 9a9d040ff..d58975640 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/StructureScript.java @@ -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.LootFunctionBuilder; 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.SetMarkFunctionBuilder; import com.dfsek.terra.addons.terrascript.script.builders.StateFunctionBuilder; @@ -77,7 +76,6 @@ public class StructureScript implements Structure, Keyed { .registerFunction("block", new BlockFunctionBuilder(platform)) .registerFunction("debugBlock", new BlockFunctionBuilder(platform)) .registerFunction("structure", new StructureFunctionBuilder(registry, platform)) - .registerFunction("randomInt", new RandomFunctionBuilder()) .registerFunction("recursions", new RecursionsFunctionBuilder()) .registerFunction("setMark", new SetMarkFunctionBuilder()) .registerFunction("getMark", new GetMarkFunctionBuilder()) @@ -130,16 +128,16 @@ public class StructureScript implements Structure, Keyed { @Override @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); - boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, 0)); + boolean result = applyBlock(new TerraImplementationArguments(location, rotation, 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, Rotation rotation, int recursions) { 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); return result; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java index d768b30ec..4844b2d9e 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/TerraImplementationArguments.java @@ -20,16 +20,14 @@ import com.dfsek.terra.api.world.WritableWorld; public class TerraImplementationArguments implements ImplementationArguments { private final Rotation rotation; - private final RandomGenerator random; private final WritableWorld world; private final Map 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, WritableWorld world, int recursions) { this.rotation = rotation; - this.random = random; this.world = world; this.recursions = recursions; this.origin = origin; @@ -39,10 +37,6 @@ public class TerraImplementationArguments implements ImplementationArguments { return recursions; } - public RandomGenerator getRandom() { - return random; - } - public Rotation getRotation() { return rotation; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/RandomFunctionBuilder.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/RandomFunctionBuilder.java deleted file mode 100644 index 6cfeaa52d..000000000 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/builders/RandomFunctionBuilder.java +++ /dev/null @@ -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 { - @SuppressWarnings("unchecked") - @Override - public RandomFunction build(List> argumentList, Position position) { - return new RandomFunction((Returnable) 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; - } -} diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/RandomFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/RandomFunction.java deleted file mode 100644 index 3170d2645..000000000 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/RandomFunction.java +++ /dev/null @@ -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 { - private final Returnable numberReturnable; - private final Position position; - - public RandomFunction(Returnable 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; - } -} diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java index 51fb47054..57c7dd943 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/StructureFunction.java @@ -67,31 +67,20 @@ public class StructureFunction implements Function { String app = id.apply(implementationArguments, scope); 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) { return structureScript.generate(arguments.getOrigin(), arguments.getWorld() .buffer(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, scope).intValue(), FastMath.roundToInt(xz.getZ())), - arguments.getRandom(), - arguments.getRotation().rotate(rotation1), arguments.getRecursions() + 1); + arguments.getRotation(), arguments.getRecursions() + 1); } return script.generate(arguments.getOrigin(), arguments.getWorld() .buffer(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, scope).intValue(), FastMath.roundToInt(xz.getZ())), - arguments.getRandom(), - arguments.getRotation().rotate(rotation1)); + arguments.getRotation(), arguments.getWorld().getSeed()); }).orElseGet(() -> { LOGGER.error("No such structure {}", app); return false; diff --git a/common/api/src/main/java/com/dfsek/terra/api/structure/Structure.java b/common/api/src/main/java/com/dfsek/terra/api/structure/Structure.java index 20aa70d1d..48fb5a069 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/structure/Structure.java +++ b/common/api/src/main/java/com/dfsek/terra/api/structure/Structure.java @@ -9,11 +9,12 @@ package com.dfsek.terra.api.structure; 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.vector.Vector3Int; 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, Rotation rotation, Long Seed); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/MathUtil.java b/common/api/src/main/java/com/dfsek/terra/api/util/MathUtil.java index 3c95df139..8e78f1f8b 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/MathUtil.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/MathUtil.java @@ -173,4 +173,21 @@ public final class MathUtil { 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); + } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/gameplay/BoneMealTaskMixin.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/gameplay/BoneMealTaskMixin.java index 62a50c376..df17f905a 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/gameplay/BoneMealTaskMixin.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/mixin/gameplay/BoneMealTaskMixin.java @@ -1,6 +1,8 @@ package com.dfsek.terra.mod.mixin.gameplay; +import com.dfsek.terra.api.world.World; + import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.ai.brain.task.BoneMealTask; @@ -43,14 +45,13 @@ public class BoneMealTaskMixin { if(canGrow != null) { RandomGenerator random = MinecraftAdapter.adapt(world.getRandom()); 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; } cir.setReturnValue(true); return; } cir.setReturnValue(false); - return; } } } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/FertilizableUtil.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/FertilizableUtil.java index a550660ca..fcb4e87bd 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/FertilizableUtil.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/FertilizableUtil.java @@ -27,7 +27,7 @@ public class FertilizableUtil { Structure canGrow = config.getCanGrow(); if(canGrow != null) { 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; } } @@ -38,7 +38,7 @@ public class FertilizableUtil { } } 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; } }