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 438546137..1332feddf 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,9 +6,10 @@ import cloud.commandframework.arguments.standard.EnumArgument; import cloud.commandframework.arguments.standard.LongArgument; import cloud.commandframework.context.CommandContext; -import java.util.Random; - -import com.dfsek.terra.addons.manifest.api.AddonInitializer; +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; @@ -22,6 +23,8 @@ import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.Rotation; import com.dfsek.terra.api.util.reflection.TypeKey; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; public class StructureCommandAddon implements AddonInitializer { @Inject diff --git a/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PaddedGridDistributor.java b/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PaddedGridDistributor.java index 1779c98d1..b4a438d4c 100644 --- a/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PaddedGridDistributor.java +++ b/common/addons/config-distributors/src/main/java/com/dfsek/terra/addons/feature/distributor/distributors/PaddedGridDistributor.java @@ -1,6 +1,7 @@ package com.dfsek.terra.addons.feature.distributor.distributors; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; import com.dfsek.terra.api.structure.feature.Distributor; import com.dfsek.terra.api.util.MathUtil; @@ -24,8 +25,9 @@ public class PaddedGridDistributor implements Distributor { int cellX = Math.floorDiv(x, cellWidth); int cellZ = Math.floorDiv(z, cellWidth); - Random random = new Random((MathUtil.murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt); - + RandomGenerator random = RandomGeneratorFactory.of("Xoroshiro128PlusPlus").create( + (murmur64(MathUtil.squash(cellX, cellZ)) ^ seed) + salt); + int pointX = random.nextInt(width) + cellX * cellWidth; int pointZ = random.nextInt(width) + cellZ * cellWidth; 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 661b820f2..027772c01 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 @@ -10,7 +10,8 @@ package com.dfsek.terra.addons.flora.flora.gen; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.block.state.properties.enums.Direction; @@ -71,7 +72,7 @@ public class TerraFlora implements Structure { } @Override - public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) { boolean doRotation = testRotation.size() > 0; int size = layers.size(); int c = ceiling ? -1 : 1; @@ -86,7 +87,9 @@ public class TerraFlora implements Structure { location.getZ(), world.getSeed()); if(doRotation) { Direction oneFace = new ArrayList<>(faces).get( - new Random(location.getX() ^ location.getZ()).nextInt(faces.size())); // Get random face. + RandomGeneratorFactory.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); } diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/GaussianRandomLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/GaussianRandomLocator.java index db1279ab9..1a3501cc8 100644 --- a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/GaussianRandomLocator.java +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/GaussianRandomLocator.java @@ -7,7 +7,8 @@ package com.dfsek.terra.addons.feature.locator.locators; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; import com.dfsek.terra.api.structure.feature.BinaryColumn; import com.dfsek.terra.api.structure.feature.Locator; @@ -39,9 +40,9 @@ public class GaussianRandomLocator implements Locator { seed = 31 * seed + column.getX(); seed = 31 * seed + column.getZ(); seed += salt; - - Random r = new Random(seed); - + + RandomGenerator r = RandomGeneratorFactory.of("Xoroshiro128PlusPlus").create(seed); + int size = points.get(r); diff --git a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java index 1f8dbd19a..93364be07 100644 --- a/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java +++ b/common/addons/config-locators/src/main/java/com/dfsek/terra/addons/feature/locator/locators/RandomLocator.java @@ -7,7 +7,8 @@ package com.dfsek.terra.addons.feature.locator.locators; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; import com.dfsek.terra.api.structure.feature.BinaryColumn; import com.dfsek.terra.api.structure.feature.Locator; @@ -35,9 +36,9 @@ public class RandomLocator implements Locator { seed = 31 * seed + column.getX(); seed = 31 * seed + column.getZ(); seed += salt; - - Random r = new Random(seed); - + + RandomGenerator r = RandomGeneratorFactory.of("Xoroshiro128PlusPlus").create(seed); + int size = points.get(r); BinaryColumnBuilder results = column.newBinaryColumn(); 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 f51ac47ef..931ae09e5 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 @@ -9,7 +9,7 @@ package com.dfsek.terra.addons.ore.ores; import java.util.BitSet; import java.util.Map; -import java.util.Random; +import java.util.random.RandomGenerator; import com.dfsek.terra.api.block.BlockType; import com.dfsek.terra.api.block.state.BlockState; diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Entry.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Entry.java index 106147229..6bd3b615f 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Entry.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Entry.java @@ -12,7 +12,7 @@ import org.json.simple.JSONObject; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to apply functions with + * @param r The RandomGenerator instance to apply functions with * * @return ItemStack - The ItemStack with all functions applied. */ - public ItemStack getItem(Random r) { + public ItemStack getItem(RandomGenerator r) { ItemStack item = this.item.newItemStack(1); for(LootFunction f : functions) { item = f.apply(item, r); diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/LootTableImpl.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/LootTableImpl.java index cebf93ef2..7aa310bde 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/LootTableImpl.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/LootTableImpl.java @@ -14,7 +14,7 @@ import org.json.simple.parser.ParseException; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; 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, Random r) { + public void fillInventory(Inventory i, RandomGenerator r) { List 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 getLoot(Random r) { + public List getLoot(RandomGenerator r) { List itemList = new ArrayList<>(); for(Pool pool : pools) { itemList.addAll(pool.getItems(r)); diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Pool.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Pool.java index dd80e03ec..3a2727b20 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Pool.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/Pool.java @@ -12,7 +12,7 @@ import org.json.simple.JSONObject; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; import com.dfsek.terra.api.Platform; import com.dfsek.terra.api.inventory.ItemStack; @@ -50,14 +50,14 @@ public class Pool { } /** - * Fetches a list of items from the pool using the provided Random instance. + * Fetches a list of items from the pool using the provided RandomGenerator instance. * - * @param r The Random instance to use. + * @param r The RandomGenerator instance to use. * * @return List<ItemStack> - The list of items fetched. */ - public List getItems(Random r) { - + public List getItems(RandomGenerator r) { + int rolls = r.nextInt(max - min + 1) + min; List items = new ArrayList<>(); for(int i = 0; i < rolls; i++) { diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/AmountFunction.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/AmountFunction.java index 2605840f6..f33e87858 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/AmountFunction.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/AmountFunction.java @@ -8,7 +8,7 @@ package com.dfsek.terra.addons.structure.structures.loot.functions; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to use. + * @param r The RandomGenerator instance to use. * * @return - ItemStack - The mutated ItemStack. */ @Override - public ItemStack apply(ItemStack original, Random r) { + public ItemStack apply(ItemStack original, RandomGenerator r) { original.setAmount(r.nextInt(max - min + 1) + min); return original; } diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/DamageFunction.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/DamageFunction.java index c90090199..6e688b50e 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/DamageFunction.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/DamageFunction.java @@ -7,7 +7,7 @@ package com.dfsek.terra.addons.structure.structures.loot.functions; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to use. + * @param r The RandomGenerator instance to use. * * @return - ItemStack - The mutated ItemStack. */ @Override - public ItemStack apply(ItemStack original, Random r) { + public ItemStack apply(ItemStack original, RandomGenerator r) { if(original == null) return null; if(!original.isDamageable()) return original; ItemMeta meta = original.getItemMeta(); diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/EnchantFunction.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/EnchantFunction.java index e741bd9f5..8d8e8a787 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/EnchantFunction.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/EnchantFunction.java @@ -14,7 +14,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to use. + * @param r The RandomGenerator instance to use. * * @return - ItemStack - The mutated ItemStack. */ @Override - public ItemStack apply(ItemStack original, Random r) { + public ItemStack apply(ItemStack original, RandomGenerator r) { if(original.getItemMeta() == null) return original; double enchant = (r.nextDouble() * (max - min)) + min; diff --git a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/LootFunction.java b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/LootFunction.java index a881ca634..1a3c03f0c 100644 --- a/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/LootFunction.java +++ b/common/addons/config-structure/src/main/java/com/dfsek/terra/addons/structure/structures/loot/functions/LootFunction.java @@ -8,7 +8,7 @@ package com.dfsek.terra.addons.structure.structures.loot.functions; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to use. + * @param r The RandomGenerator instance to use. * * @return - ItemStack - The mutated ItemStack. */ - ItemStack apply(ItemStack original, Random r); + ItemStack apply(ItemStack original, RandomGenerator r); } 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 6baf88b7a..942f53ca3 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 @@ -8,7 +8,8 @@ package com.dfsek.terra.addons.generation.feature; import java.util.Collections; -import java.util.Random; +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; @@ -52,35 +53,37 @@ public class FeatureGenerationStage implements GenerationStage, StringIdentifiab int tx = cx + chunkX; int tz = cz + chunkZ; world.getBiomeProvider() - .getColumn(tx, tz, world) - .forRanges(resolution, (min, max, biome) -> { - for(int subChunkX = 0; subChunkX < resolution; subChunkX++) { - for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) { - int x = subChunkX + tx; - int z = subChunkZ + tz; - long coordinateSeed = (seed * 31 + x) * 31 + z; - Column column = world.column(x, z); - biome.getContext() - .get(biomeFeaturesKey) - .getFeatures() - .getOrDefault(this, Collections.emptyList()) - .forEach(feature -> { - platform.getProfiler().push(feature.getID()); - if(feature.getDistributor().matches(x, z, seed)) { - feature.getLocator() - .getSuitableCoordinates(column.clamp(min, max)) - .forEach(y -> feature.getStructure(world, x, y, z) - .generate(Vector3Int.of(x, y, z), - world, - new Random(coordinateSeed * 31 + y), - Rotation.NONE) - ); - } - platform.getProfiler().pop(feature.getID()); - }); - } - } - }); + .getColumn(tx, tz, world) + .forRanges(resolution, (min, max, biome) -> { + for(int subChunkX = 0; subChunkX < resolution; subChunkX++) { + for(int subChunkZ = 0; subChunkZ < resolution; subChunkZ++) { + int x = subChunkX + tx; + int z = subChunkZ + tz; + long coordinateSeed = (seed * 31 + x) * 31 + z; + Column column = world.column(x, z); + biome.getContext() + .get(biomeFeaturesKey) + .getFeatures() + .getOrDefault(this, Collections.emptyList()) + .forEach(feature -> { + platform.getProfiler().push(feature.getID()); + if(feature.getDistributor().matches(x, z, seed)) { + feature.getLocator() + .getSuitableCoordinates(column.clamp(min, max)) + .forEach(y -> feature.getStructure(world, x, y, z) + .generate(Vector3Int.of(x, y, z), + world, + RandomGeneratorFactory.of( + "Xoroshiro128PlusPlus") + .create(coordinateSeed * 31 + y), + Rotation.NONE) + ); + } + platform.getProfiler().pop(feature.getID()); + }); + } + } + }); } } platform.getProfiler().pop(profile); 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 bac5f4373..b8da27192 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 @@ -1,6 +1,6 @@ package com.dfsek.terra.addons.palette.shortcut.block; -import java.util.Random; +import java.util.random.RandomGenerator; 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, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) { 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 30b2d5984..5fbc42028 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 @@ -1,6 +1,6 @@ package com.dfsek.terra.addons.structure.mutator; -import java.util.Random; +import java.util.random.RandomGenerator; import com.dfsek.terra.api.registry.key.Keyed; import com.dfsek.terra.api.registry.key.RegistryKey; @@ -32,7 +32,7 @@ public class MutatedStructure implements Structure, Keyed { } @Override - public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) { return base.generate(location, world .buffer() 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 12ce1f42b..8d7a22324 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 @@ -7,7 +7,7 @@ package com.dfsek.terra.addons.sponge; -import java.util.Random; +import java.util.random.RandomGenerator; 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 { } @Override - public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation) { 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 45b004a22..c031baa66 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 @@ -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; +import java.util.random.RandomGenerator; 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 { @Override @SuppressWarnings("try") - public boolean generate(Vector3Int location, WritableWorld world, Random random, Rotation rotation) { + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator 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, Random random, Rotation rotation, int recursions) { + + public boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation, int recursions) { platform.getProfiler().push(profile); boolean result = applyBlock(new TerraImplementationArguments(location, rotation, random, world, recursions)); platform.getProfiler().pop(profile); 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 97e69feca..bf38eb183 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 @@ -9,7 +9,7 @@ package com.dfsek.terra.addons.terrascript.script; import java.util.HashMap; import java.util.Map; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random random; + 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, Random random, WritableWorld world, int recursions) { + + public TerraImplementationArguments(Vector3Int origin, Rotation rotation, RandomGenerator random, WritableWorld world, int recursions) { this.rotation = rotation; this.random = random; this.world = world; @@ -38,8 +38,8 @@ public class TerraImplementationArguments implements ImplementationArguments { public int getRecursions() { return recursions; } - - public Random getRandom() { + + public RandomGenerator getRandom() { return random; } diff --git a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java index 67dd7fad3..8ddc65d1b 100644 --- a/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java +++ b/common/addons/structure-terrascript-loader/src/main/java/com/dfsek/terra/addons/terrascript/script/functions/LootFunction.java @@ -10,8 +10,6 @@ package com.dfsek.terra.addons.terrascript.script.functions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.Random; - 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; @@ -30,6 +28,9 @@ import com.dfsek.terra.api.util.RotationUtil; import com.dfsek.terra.api.util.vector.Vector2; import com.dfsek.terra.api.util.vector.Vector3; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; + public class LootFunction implements Function { private static final Logger LOGGER = LoggerFactory.getLogger(LootFunction.class); @@ -64,34 +65,35 @@ public class LootFunction implements Function { registry.get(RegistryKey.parse(id)) - .ifPresentOrElse(table -> { - Vector3 apply = Vector3.of((int) Math.round(xz.getX()), - y.apply(implementationArguments, scope) - .intValue(), - (int) Math.round(xz.getZ())).mutable().add(arguments.getOrigin()).immutable(); - - try { - BlockEntity data = arguments.getWorld().getBlockEntity(apply); - if(!(data instanceof Container container)) { - LOGGER.error("Failed to place loot at {}; block {} is not a container", - apply, data); - return; - } - - LootPopulateEvent event = new LootPopulateEvent(container, table, - arguments.getWorld().getPack(), script); - platform.getEventManager().callEvent(event); - if(event.isCancelled()) return; - - event.getTable().fillInventory(container.getInventory(), - new Random(apply.hashCode())); - data.update(false); - } catch(Exception e) { - LOGGER.error("Could not apply loot at {}", apply, e); - e.printStackTrace(); - } - }, - () -> LOGGER.error("No such loot table {}", id)); + .ifPresentOrElse(table -> { + Vector3 apply = Vector3.of(FastMath.roundToInt(xz.getX()), + y.apply(implementationArguments, scope) + .intValue(), + FastMath.roundToInt(xz.getZ())).mutable().add(arguments.getOrigin()).immutable(); + + try { + BlockEntity data = arguments.getWorld().getBlockEntity(apply); + if(!(data instanceof Container container)) { + LOGGER.error("Failed to place loot at {}; block {} is not a container", + apply, data); + return; + } + + LootPopulateEvent event = new LootPopulateEvent(container, table, + arguments.getWorld().getPack(), script); + platform.getEventManager().callEvent(event); + if(event.isCancelled()) return; + + event.getTable().fillInventory(container.getInventory(), + RandomGeneratorFactory.of( + "Xoroshiro128PlusPlus").create(apply.hashCode())); + data.update(false); + } catch(Exception e) { + LOGGER.error("Could not apply loot at {}", apply, e); + e.printStackTrace(); + } + }, + () -> LOGGER.error("No such loot table {}", id)); return null; } diff --git a/common/api/src/main/java/com/dfsek/terra/api/structure/LootTable.java b/common/api/src/main/java/com/dfsek/terra/api/structure/LootTable.java index 3108dd1f3..ecfe735bd 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/structure/LootTable.java +++ b/common/api/src/main/java/com/dfsek/terra/api/structure/LootTable.java @@ -10,7 +10,7 @@ package com.dfsek.terra.api.structure; import org.jetbrains.annotations.ApiStatus.Experimental; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; 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 Random instance to use. + * @param r The The RandomGenerator instance to use. */ - void fillInventory(Inventory i, Random r); - + void fillInventory(Inventory i, RandomGenerator r); + /** - * Fetches a list of ItemStacks from the loot table using the given Random instance. + * Fetches a list of ItemStacks from the loot table using the given RandomGenerator instance. * - * @param r The Random instance to use. + * @param r The RandomGenerator instance to use. * * @return List<ItemStack> - The list of loot fetched. */ - List getLoot(Random r); + List getLoot(RandomGenerator r); } 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 d5f3ca7e2..d1e9a83ec 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 @@ -7,7 +7,7 @@ package com.dfsek.terra.api.structure; -import java.util.Random; +import java.util.random.RandomGenerator; 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, Random random, Rotation rotation); + boolean generate(Vector3Int location, WritableWorld world, RandomGenerator random, Rotation rotation); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/ConstantRange.java b/common/api/src/main/java/com/dfsek/terra/api/util/ConstantRange.java index 68b062d21..6b1231506 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/ConstantRange.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/ConstantRange.java @@ -10,7 +10,7 @@ package com.dfsek.terra.api.util; import org.jetbrains.annotations.NotNull; import java.util.Iterator; -import java.util.Random; +import java.util.random.RandomGenerator; public class ConstantRange implements Range { @@ -36,7 +36,7 @@ public class ConstantRange implements Range { } @Override - public int get(Random r) { + public int get(RandomGenerator r) { return r.nextInt(min, max); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/PopulationUtil.java b/common/api/src/main/java/com/dfsek/terra/api/util/PopulationUtil.java index f3ea39f10..2ec5f2d91 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/PopulationUtil.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/PopulationUtil.java @@ -7,18 +7,20 @@ package com.dfsek.terra.api.util; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.random.RandomGeneratorFactory; import com.dfsek.terra.api.world.chunk.Chunk; public final class PopulationUtil { - public static Random getRandom(Chunk c) { + public static RandomGenerator getRandom(Chunk c) { return getRandom(c, 0); } - - public static Random getRandom(Chunk c, long salt) { - return new Random(getCarverChunkSeed(c.getX(), c.getZ(), c.getWorld().getSeed() + salt)); + + public static RandomGenerator getRandom(Chunk c, long salt) { + return RandomGeneratorFactory.of("Xoroshiro128PlusPlus").create( + getCarverChunkSeed(c.getX(), c.getZ(), c.getWorld().getSeed() + salt)); } /** @@ -31,7 +33,7 @@ public final class PopulationUtil { * @return long - The carver seed. */ public static long getCarverChunkSeed(int chunkX, int chunkZ, long seed) { - Random r = new Random(seed); + RandomGenerator r = RandomGeneratorFactory.of("Xoroshiro128PlusPlus").create(seed); return chunkX * r.nextLong() ^ chunkZ * r.nextLong() ^ seed; } } diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/Range.java b/common/api/src/main/java/com/dfsek/terra/api/util/Range.java index f42bc174d..c851bd621 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/Range.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/Range.java @@ -10,17 +10,17 @@ package com.dfsek.terra.api.util; import org.jetbrains.annotations.NotNull; import java.util.Iterator; -import java.util.Random; import java.util.function.Supplier; +import java.util.random.RandomGenerator; public interface Range extends Iterable { Range multiply(int mult); Range reflect(int pt); - - int get(Random r); - + + int get(RandomGenerator r); + Range intersects(Range other); Range add(int add); diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/collection/ProbabilityCollection.java b/common/api/src/main/java/com/dfsek/terra/api/util/collection/ProbabilityCollection.java index 4aad8b7e1..8d1a06f43 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/collection/ProbabilityCollection.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/collection/ProbabilityCollection.java @@ -15,9 +15,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; -import java.util.Random; import java.util.Set; import java.util.function.Function; +import java.util.random.RandomGenerator; import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.util.MathUtil; @@ -43,7 +43,7 @@ public class ProbabilityCollection implements Collection { } @SuppressWarnings("unchecked") - public E get(Random r) { + public E get(RandomGenerator r) { if(array.length == 0) return null; return (E) array[r.nextInt(array.length)]; } @@ -197,7 +197,7 @@ public class ProbabilityCollection implements Collection { } @Override - public T get(Random r) { + public T get(RandomGenerator r) { return single; } diff --git a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/generator/BukkitChunkGeneratorWrapper.java b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/generator/BukkitChunkGeneratorWrapper.java index bd6796bad..192dbecf7 100644 --- a/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/generator/BukkitChunkGeneratorWrapper.java +++ b/platforms/bukkit/common/src/main/java/com/dfsek/terra/bukkit/generator/BukkitChunkGeneratorWrapper.java @@ -27,7 +27,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; -import java.util.Random; +import java.util.random.RandomGenerator; +import java.util.stream.Collectors; import com.dfsek.terra.api.block.state.BlockState; import com.dfsek.terra.api.config.ConfigPack; @@ -62,7 +63,7 @@ public class BukkitChunkGeneratorWrapper extends org.bukkit.generator.ChunkGener } @Override - public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull ChunkData chunkData) { + public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull RandomGenerator random, int x, int z, @NotNull ChunkData chunkData) { BukkitWorldProperties properties = new BukkitWorldProperties(worldInfo); delegate.generateChunkData(new BukkitProtoChunk(chunkData), properties, pack.getBiomeProvider(), x, z); } diff --git a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftAdapter.java b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftAdapter.java index 25ca7e4c5..973861bd3 100644 --- a/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftAdapter.java +++ b/platforms/mixin-common/src/main/java/com/dfsek/terra/mod/util/MinecraftAdapter.java @@ -18,11 +18,14 @@ package com.dfsek.terra.mod.util; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.random.Random; import net.minecraft.world.HeightLimitView; import com.dfsek.terra.api.util.vector.Vector3; import com.dfsek.terra.api.world.info.WorldProperties; +import java.util.random.RandomGenerator; + public final class MinecraftAdapter { @@ -53,4 +56,48 @@ public final class MinecraftAdapter { } }; } + + public static RandomGenerator adapt(Random random) { + return new RandomGenerator() { + @Override + public boolean nextBoolean() { + return random.nextBoolean(); + } + + @Override + public float nextFloat() { + return random.nextFloat(); + } + + @Override + public double nextDouble() { + return random.nextDouble(); + } + + @Override + public int nextInt() { + return random.nextInt(); + } + + @Override + public int nextInt(int bound) { + return random.nextInt(bound); + } + + @Override + public long nextLong() { + return random.nextLong(); + } + + @Override + public double nextGaussian() { + return random.nextGaussian(); + } + + @Override + public int nextInt(int origin, int bound) { + return random.nextBetween(origin, bound); + } + }; + } }