From be62ba5c000258c72b3fd566368232a50556c1d5 Mon Sep 17 00:00:00 2001 From: Unknown Date: Mon, 30 Dec 2019 15:43:41 -0500 Subject: [PATCH] optimized structure seed code --- .../kaptainwutax/seedcracker/SeedCracker.java | 7 +- .../seedcracker/cracker/StructureData.java | 77 ++++++++++++------- .../seedcracker/cracker/TimeMachine.java | 7 +- .../kaptainwutax/seedcracker/util/Seeds.java | 11 +++ 4 files changed, 65 insertions(+), 37 deletions(-) create mode 100644 src/main/java/kaptainwutax/seedcracker/util/Seeds.java diff --git a/src/main/java/kaptainwutax/seedcracker/SeedCracker.java b/src/main/java/kaptainwutax/seedcracker/SeedCracker.java index be6062a..68438de 100644 --- a/src/main/java/kaptainwutax/seedcracker/SeedCracker.java +++ b/src/main/java/kaptainwutax/seedcracker/SeedCracker.java @@ -6,8 +6,8 @@ import kaptainwutax.seedcracker.cracker.population.DecoratorData; import kaptainwutax.seedcracker.finder.FinderQueue; import kaptainwutax.seedcracker.render.RenderQueue; import kaptainwutax.seedcracker.util.Log; +import kaptainwutax.seedcracker.util.Rand; import net.fabricmc.api.ModInitializer; -import net.minecraft.world.gen.ChunkRandom; import net.minecraft.world.level.LevelProperties; import java.util.ArrayList; @@ -96,9 +96,8 @@ public class SeedCracker implements ModInitializer { this.onBiomeData(null); } else if(this.structureSeeds != null && structureData != null) { this.structureSeeds.removeIf(structureSeed -> { - ChunkRandom chunkRandom = new ChunkRandom(); - chunkRandom.setStructureSeed(structureSeed, structureData.getRegionX(), structureData.getRegionZ(), structureData.getSalt()); - return !structureData.test(chunkRandom); + Rand rand = new Rand(0L); + return !structureData.test(structureSeed, rand); }); this.onBiomeData(null); diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/StructureData.java b/src/main/java/kaptainwutax/seedcracker/cracker/StructureData.java index 8d01cf7..a6362dc 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/StructureData.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/StructureData.java @@ -1,10 +1,13 @@ package kaptainwutax.seedcracker.cracker; +import kaptainwutax.seedcracker.util.Seeds; +import kaptainwutax.seedcracker.util.Rand; import net.minecraft.util.math.ChunkPos; -import net.minecraft.world.gen.ChunkRandom; public class StructureData { + private int chunkX; + private int chunkZ; private int regionX; private int regionZ; private int offsetX; @@ -16,6 +19,14 @@ public class StructureData { this.featureType.build(this, chunkPos); } + public int getChunkX() { + return this.chunkX; + } + + public int getChunkZ() { + return this.chunkZ; + } + public int getRegionX() { return this.regionX; } @@ -40,8 +51,9 @@ public class StructureData { return this.featureType; } - public boolean test(ChunkRandom rand) { - return this.featureType.test(rand, this.offsetX, this.offsetZ); + public boolean test(long structureSeed, Rand rand) { + Seeds.setStructureSeed(rand, structureSeed, this.regionX, this.regionZ, this.getSalt()); + return this.featureType.test(rand, this, structureSeed); } @Override @@ -69,6 +81,9 @@ public class StructureData { int chunkX = chunkPos.x; int chunkZ = chunkPos.z; + data.chunkX = chunkX; + data.chunkZ = chunkZ; + chunkX = chunkX < 0 ? chunkX - this.distance + 1 : chunkX; chunkZ = chunkZ < 0 ? chunkZ - this.distance + 1 : chunkZ; @@ -86,86 +101,92 @@ public class StructureData { data.offsetZ = chunkPos.z - regionZ; } - public abstract boolean test(ChunkRandom rand, int x, int z); + public abstract boolean test(Rand rand, StructureData data, long structureSeed); } public static final FeatureType DESERT_PYRAMID = new FeatureType(14357617, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(24) == x && rand.nextInt(24) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(24) == data.getOffsetX() && rand.nextInt(24) == data.getOffsetZ(); } }; public static final FeatureType IGLOO = new FeatureType(14357618, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(24) == x && rand.nextInt(24) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(24) == data.getOffsetX() && rand.nextInt(24) == data.getOffsetZ(); } }; public static final FeatureType JUNGLE_TEMPLE = new FeatureType(14357619, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(24) == x && rand.nextInt(24) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(24) == data.getOffsetX() && rand.nextInt(24) == data.getOffsetZ(); } }; public static final FeatureType SWAMP_HUT = new FeatureType(14357620, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(24) == x && rand.nextInt(24) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(24) == data.getOffsetX() && rand.nextInt(24) == data.getOffsetZ(); } }; public static final FeatureType OCEAN_RUIN = new FeatureType(14357621, 16) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(8) == x && rand.nextInt(8) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(8) == data.getOffsetX() && rand.nextInt(8) == data.getOffsetZ(); } }; public static final FeatureType SHIPWRECK = new FeatureType(165745295, 16) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(8) == x && rand.nextInt(8) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return rand.nextInt(8) == data.getOffsetX() && rand.nextInt(8) == data.getOffsetZ(); } }; public static final FeatureType PILLAGER_OUTPOST = new FeatureType(165745296, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return rand.nextInt(24) == x && rand.nextInt(24) == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + if(rand.nextInt(24) != data.getOffsetX() || rand.nextInt(24) != data.getOffsetZ())return false; + + int xo = data.getChunkX() >> 4; + int zo = data.getChunkZ() >> 4; + rand.setSeed((long)(xo ^ zo << 4) ^ structureSeed, true); + rand.nextInt(); + return rand.nextInt(5) == 0; } }; public static final FeatureType END_CITY = new FeatureType(10387313, 20) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return (rand.nextInt(9) + rand.nextInt(9)) / 2 == x - && (rand.nextInt(9) + rand.nextInt(9)) / 2 == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return (rand.nextInt(9) + rand.nextInt(9)) / 2 == data.getOffsetX() + && (rand.nextInt(9) + rand.nextInt(9)) / 2 == data.getOffsetZ(); } }; public static final FeatureType OCEAN_MONUMENT = new FeatureType(10387313, 32) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return (rand.nextInt(27) + rand.nextInt(27)) / 2 == x - && (rand.nextInt(27) + rand.nextInt(27)) / 2 == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return (rand.nextInt(27) + rand.nextInt(27)) / 2 == data.getOffsetX() + && (rand.nextInt(27) + rand.nextInt(27)) / 2 == data.getOffsetZ(); } }; public static final FeatureType BURIED_TREASURE = new FeatureType(10387320, 1) { @Override - public boolean test(ChunkRandom rand, int x, int z) { + public boolean test(Rand rand, StructureData data, long structureSeed) { return rand.nextFloat() < 0.01f; } }; public static final FeatureType WOODLAND_MANSION = new FeatureType(10387319, 80) { @Override - public boolean test(ChunkRandom rand, int x, int z) { - return (rand.nextInt(60) + rand.nextInt(60)) / 2 == x - && (rand.nextInt(60) + rand.nextInt(60)) / 2 == z; + public boolean test(Rand rand, StructureData data, long structureSeed) { + return (rand.nextInt(60) + rand.nextInt(60)) / 2 == data.getOffsetX() + && (rand.nextInt(60) + rand.nextInt(60)) / 2 == data.getOffsetZ(); } }; diff --git a/src/main/java/kaptainwutax/seedcracker/cracker/TimeMachine.java b/src/main/java/kaptainwutax/seedcracker/cracker/TimeMachine.java index ea0703a..ffa1fac 100644 --- a/src/main/java/kaptainwutax/seedcracker/cracker/TimeMachine.java +++ b/src/main/java/kaptainwutax/seedcracker/cracker/TimeMachine.java @@ -4,7 +4,6 @@ import kaptainwutax.seedcracker.cracker.population.DecoratorData; import kaptainwutax.seedcracker.util.Log; import kaptainwutax.seedcracker.util.Rand; import kaptainwutax.seedcracker.util.math.LCG; -import net.minecraft.world.gen.ChunkRandom; import java.util.ArrayList; import java.util.List; @@ -27,7 +26,7 @@ public class TimeMachine { public List bruteforceRegion(int pillarSeed, int region, long size, List structureDataList, List decoratorDataList) { List result = new ArrayList<>(); - ChunkRandom chunkRandom = new ChunkRandom(); + Rand rand = new Rand(0L); long start = region * size; long end = start + size; @@ -38,9 +37,7 @@ public class TimeMachine { for(StructureData structureData: structureDataList) { if(!goodSeed)break; - chunkRandom.setStructureSeed(structureSeed, structureData.getRegionX(), - structureData.getRegionZ(), structureData.getSalt()); - if(!structureData.test(chunkRandom))goodSeed = false; + if(!structureData.test(structureSeed, rand))goodSeed = false; } for(DecoratorData decoratorData : decoratorDataList) { diff --git a/src/main/java/kaptainwutax/seedcracker/util/Seeds.java b/src/main/java/kaptainwutax/seedcracker/util/Seeds.java new file mode 100644 index 0000000..76e848f --- /dev/null +++ b/src/main/java/kaptainwutax/seedcracker/util/Seeds.java @@ -0,0 +1,11 @@ +package kaptainwutax.seedcracker.util; + +public class Seeds { + + public static long setStructureSeed(Rand rand, long worldSeed, int regionX, int regionZ, int salt) { + long seed = (long)regionX * 341873128712L + (long)regionZ * 132897987541L + worldSeed + (long)salt; + rand.setSeed(seed, true); + return seed; + } + +}