Compare commits
23 Commits
v0.0.1-alpha
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c8875b2d75 | |||
| 56d8d47289 | |||
| 6c0760ae01 | |||
| 8db7d96727 | |||
| 3f57818c35 | |||
| 4e28f711ed | |||
| 0abeaeabdb | |||
| be62ba5c00 | |||
| 5ed8e517e4 | |||
| 4a0c86c36a | |||
| 5cfa74ac19 | |||
| a5da8b83e8 | |||
| 79e7b00210 | |||
| cb85a794d1 | |||
| 4a8f4c7a4d | |||
| f9d2e3d01b | |||
| f9f3c88cfd | |||
| 235fff9426 | |||
| 7a49baa19c | |||
| 10bb559a1e | |||
| b86892c10a | |||
| 525d67f0f1 | |||
| 118e056c06 |
+2
-2
@@ -3,8 +3,8 @@ org.gradle.jvmargs=-Xmx1G
|
|||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/use
|
# check these on https://fabricmc.net/use
|
||||||
minecraft_version=1.15
|
minecraft_version=1.14.4
|
||||||
yarn_mappings=1.15+build.2
|
yarn_mappings=1.14.4+build.15
|
||||||
loader_version=0.7.2+build.174
|
loader_version=0.7.2+build.174
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
|
|||||||
@@ -1,44 +1,96 @@
|
|||||||
package kaptainwutax.seedcracker;
|
package kaptainwutax.seedcracker;
|
||||||
|
|
||||||
import io.netty.util.internal.ConcurrentSet;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import kaptainwutax.seedcracker.cracker.*;
|
import kaptainwutax.seedcracker.cracker.*;
|
||||||
import kaptainwutax.seedcracker.cracker.population.DecoratorData;
|
import kaptainwutax.seedcracker.cracker.population.PopulationData;
|
||||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||||
import kaptainwutax.seedcracker.render.RenderQueue;
|
import kaptainwutax.seedcracker.render.RenderQueue;
|
||||||
import kaptainwutax.seedcracker.util.Log;
|
import kaptainwutax.seedcracker.util.Log;
|
||||||
import kaptainwutax.seedcracker.util.Rand;
|
import kaptainwutax.seedcracker.util.Rand;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.minecraft.util.math.BlockBox;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
|
import net.minecraft.util.math.MutableIntBoundingBox;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.Biomes;
|
||||||
|
import net.minecraft.world.biome.layer.BiomeLayerSampler;
|
||||||
|
import net.minecraft.world.biome.layer.BiomeLayers;
|
||||||
|
import net.minecraft.world.biome.source.BiomeSourceType;
|
||||||
import net.minecraft.world.gen.ChunkRandom;
|
import net.minecraft.world.gen.ChunkRandom;
|
||||||
import net.minecraft.world.gen.feature.Feature;
|
import net.minecraft.world.gen.feature.Feature;
|
||||||
import net.minecraft.world.gen.feature.StrongholdFeature;
|
import net.minecraft.world.gen.feature.StrongholdFeature;
|
||||||
|
import net.minecraft.world.level.LevelGeneratorType;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Random;
|
||||||
|
|
||||||
public class SeedCracker implements ModInitializer {
|
public class SeedCracker implements ModInitializer {
|
||||||
|
|
||||||
private static final SeedCracker INSTANCE = new SeedCracker();
|
private static final SeedCracker INSTANCE = new SeedCracker();
|
||||||
|
|
||||||
public List<Long> worldSeeds = null;
|
public List<Long> worldSeeds = null;
|
||||||
public Set<Long> structureSeeds = null;
|
public List<Long> structureSeeds = null;
|
||||||
public List<Integer> pillarSeeds = null;
|
public List<Integer> pillarSeeds = null;
|
||||||
|
|
||||||
private TimeMachine timeMachine = new TimeMachine();
|
private TimeMachine timeMachine = new TimeMachine();
|
||||||
private List<StructureData> structureCache = new ArrayList<>();
|
private List<StructureData> structureCache = new ArrayList<>();
|
||||||
private List<DecoratorData> decoratorCache = new ArrayList<>();
|
private List<PopulationData> populationCache = new ArrayList<>();
|
||||||
private List<BiomeData> biomeCache = new ArrayList<>();
|
private List<BiomeData> biomeCache = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
RenderQueue.get().add("hand", FinderQueue.get()::renderFinders);
|
RenderQueue.get().add("hand", FinderQueue.get()::renderFinders);
|
||||||
DecoratorCache.get().initialize();
|
DecoratorCache.get().initialize();
|
||||||
|
/*
|
||||||
|
System.out.println("FETCHING SEEDS============");
|
||||||
|
long structureSeed = 29131954246896L;
|
||||||
|
ChunkPos chunkPos = new ChunkPos(117, 23);
|
||||||
|
|
||||||
|
for(long j = 0; j < (1L << 16); j++) {
|
||||||
|
long worldSeed = (j << 48) | structureSeed;
|
||||||
|
|
||||||
|
if(initialize(worldSeed).contains(chunkPos)) {
|
||||||
|
System.out.println(worldSeed);
|
||||||
|
this.checkWorldSeed(worldSeed, chunkPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("FETCHING SEEDS============");
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
System.out.println(9348141881871L ^ Rand.JAVA_LCG.multiplier);
|
||||||
|
DungeonData data = new DungeonData(new ChunkPos(18, 8), Biomes.JUNGLE, new ArrayList<>(), new ArrayList<>());
|
||||||
|
data.test(-2418316773073950375L);
|
||||||
|
|
||||||
|
try {
|
||||||
|
BufferedWriter writer = new BufferedWriter(new FileWriter("kaktoos14.txt"));
|
||||||
|
|
||||||
|
for(int i = 0; i < (1 << 16); i++) {
|
||||||
|
long worldSeed = 9368770777595L | ((long)i << 48);
|
||||||
|
|
||||||
|
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||||
|
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[1];
|
||||||
|
|
||||||
|
if(sampler.sample(8, 8) == Biomes.DESERT) {
|
||||||
|
writer.write(worldSeed + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.flush();
|
||||||
|
writer.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkWorldSeed(long worldSeed, ChunkPos pos) {
|
private void checkWorldSeed(long worldSeed, ChunkPos pos) {
|
||||||
StrongholdFeature.Start start = new StrongholdFeature.Start(Feature.STRONGHOLD, pos.x, pos.z, BlockBox.empty(), 0, worldSeed);
|
StrongholdFeature.Start start = new StrongholdFeature.Start(Feature.STRONGHOLD, pos.x, pos.z, Biomes.PLAINS, MutableIntBoundingBox.empty(), 0, worldSeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SeedCracker get() {
|
public static SeedCracker get() {
|
||||||
@@ -51,7 +103,7 @@ public class SeedCracker implements ModInitializer {
|
|||||||
this.pillarSeeds = null;
|
this.pillarSeeds = null;
|
||||||
this.structureCache.clear();
|
this.structureCache.clear();
|
||||||
this.biomeCache.clear();
|
this.biomeCache.clear();
|
||||||
this.decoratorCache.clear();
|
this.populationCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean onPillarData(PillarData pillarData) {
|
public synchronized boolean onPillarData(PillarData pillarData) {
|
||||||
@@ -61,7 +113,7 @@ public class SeedCracker implements ModInitializer {
|
|||||||
this.pillarSeeds = pillarData.getPillarSeeds();
|
this.pillarSeeds = pillarData.getPillarSeeds();
|
||||||
|
|
||||||
if(this.pillarSeeds.size() > 0) {
|
if(this.pillarSeeds.size() > 0) {
|
||||||
Log.warn("Finished search with " + this.pillarSeeds + (this.pillarSeeds.size() == 1 ? " seed." : " seeds."));
|
Log.warn("Finished search with " + this.pillarSeeds);
|
||||||
} else {
|
} else {
|
||||||
Log.error("Finished search with no seeds.");
|
Log.error("Finished search with no seeds.");
|
||||||
}
|
}
|
||||||
@@ -79,25 +131,28 @@ public class SeedCracker implements ModInitializer {
|
|||||||
if(structureData != null && !this.structureCache.contains(structureData)) {
|
if(structureData != null && !this.structureCache.contains(structureData)) {
|
||||||
this.structureCache.add(structureData);
|
this.structureCache.add(structureData);
|
||||||
added = true;
|
added = true;
|
||||||
|
|
||||||
|
Log.warn("Structure added: " + structureData);
|
||||||
|
System.out.println(new Gson().toJson(structureCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.structureSeeds == null && this.pillarSeeds != null && this.structureCache.size() + this.decoratorCache.size() >= 5) {
|
if(this.structureSeeds == null && this.pillarSeeds != null && this.structureCache.size() + this.populationCache.size() >= 6) {
|
||||||
this.structureSeeds = new ConcurrentSet<>();
|
this.structureSeeds = new ArrayList<>();
|
||||||
Log.warn("Looking for structure seeds with " + this.structureCache.size() + " structure features.");
|
Log.warn("Looking for structure seeds with " + this.structureCache.size() + " structure features.");
|
||||||
Log.warn("Looking for structure seeds with " + this.decoratorCache.size() + " decorator features.");
|
Log.warn("Looking for structure seeds with " + this.populationCache.size() + " population features.");
|
||||||
|
|
||||||
this.pillarSeeds.forEach(pillarSeed -> {
|
this.pillarSeeds.forEach(pillarSeed -> {
|
||||||
timeMachine.buildStructureSeeds(pillarSeed, this.structureCache, this.decoratorCache, this.structureSeeds);
|
timeMachine.buildStructureSeeds(pillarSeed, this.structureCache, this.populationCache, this.structureSeeds);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(this.structureSeeds.size() > 0) {
|
if(this.structureSeeds.size() > 0) {
|
||||||
Log.warn("Finished search with " + this.structureSeeds + (this.structureSeeds.size() == 1 ? " seed." : " seeds."));
|
Log.warn("Finished search with " + this.structureSeeds);
|
||||||
} else {
|
} else {
|
||||||
Log.error("Finished search with no seeds.");
|
Log.error("Finished search with no seeds.");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.structureCache.clear();
|
//this.structureCache.clear();
|
||||||
this.onDecoratorData(null);
|
//this.onPopulationData(null);
|
||||||
this.onBiomeData(null);
|
this.onBiomeData(null);
|
||||||
} else if(this.structureSeeds != null && structureData != null) {
|
} else if(this.structureSeeds != null && structureData != null) {
|
||||||
this.structureSeeds.removeIf(structureSeed -> {
|
this.structureSeeds.removeIf(structureSeed -> {
|
||||||
@@ -112,11 +167,11 @@ public class SeedCracker implements ModInitializer {
|
|||||||
return added;
|
return added;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean onDecoratorData(DecoratorData decoratorData) {
|
public synchronized boolean onPopulationData(PopulationData populationData) {
|
||||||
boolean added = false;
|
boolean added = false;
|
||||||
|
|
||||||
if(decoratorData != null && !this.decoratorCache.contains(decoratorData)) {
|
if(populationData != null && !this.populationCache.contains(populationData)) {
|
||||||
this.decoratorCache.add(decoratorData);
|
this.populationCache.add(populationData);
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,21 +185,28 @@ public class SeedCracker implements ModInitializer {
|
|||||||
if(biomeData != null && !this.biomeCache.contains(biomeData)) {
|
if(biomeData != null && !this.biomeCache.contains(biomeData)) {
|
||||||
this.biomeCache.add(biomeData);
|
this.biomeCache.add(biomeData);
|
||||||
added = true;
|
added = true;
|
||||||
|
|
||||||
|
Log.warn("Biome added: " + biomeData);
|
||||||
|
System.out.println(new Gson().toJson(biomeCache));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.worldSeeds == null && this.structureSeeds != null && this.biomeCache.size() >= 5) {
|
if(this.worldSeeds == null && this.structureSeeds != null && this.biomeCache.size() >= 5) {
|
||||||
this.worldSeeds = new ArrayList<>();
|
this.worldSeeds = new ArrayList<>();
|
||||||
Log.warn("Looking for world seeds with " + this.biomeCache.size() + " biomes.");
|
Log.warn("Looking for world seeds with " + this.biomeCache.size() + " biomes.");
|
||||||
|
|
||||||
this.structureSeeds.forEach(structureSeed -> {
|
for(int i = 0; i < this.structureSeeds.size(); i++) {
|
||||||
for(long j = 0; j < (1L << 16); j++) {
|
Log.warn("Progress " + (i * 100.0f) / this.structureSeeds.size() + "%...");
|
||||||
|
|
||||||
|
long structureSeed = this.structureSeeds.get(i);
|
||||||
|
|
||||||
|
for (long j = 0; j < (1L << 16); j++) {
|
||||||
long worldSeed = (j << 48) | structureSeed;
|
long worldSeed = (j << 48) | structureSeed;
|
||||||
boolean goodSeed = true;
|
boolean goodSeed = true;
|
||||||
|
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||||
FakeBiomeSource fakeBiomeSource = new FakeBiomeSource(worldSeed);
|
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[1];
|
||||||
|
|
||||||
for(BiomeData data : this.biomeCache) {
|
for(BiomeData data : this.biomeCache) {
|
||||||
if (!data.test(fakeBiomeSource)) {
|
if (!data.test(worldSeed, sampler)) {
|
||||||
goodSeed = false;
|
goodSeed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -154,7 +216,7 @@ public class SeedCracker implements ModInitializer {
|
|||||||
this.worldSeeds.add(worldSeed);
|
this.worldSeeds.add(worldSeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
if(this.worldSeeds.size() > 0) {
|
if(this.worldSeeds.size() > 0) {
|
||||||
Log.warn("Finished search with " + this.worldSeeds + (this.worldSeeds.size() == 1 ? " seed." : " seeds."));
|
Log.warn("Finished search with " + this.worldSeeds + (this.worldSeeds.size() == 1 ? " seed." : " seeds."));
|
||||||
@@ -163,14 +225,16 @@ public class SeedCracker implements ModInitializer {
|
|||||||
}
|
}
|
||||||
} else if(this.worldSeeds != null && biomeData != null) {
|
} else if(this.worldSeeds != null && biomeData != null) {
|
||||||
this.worldSeeds.removeIf(worldSeed -> {
|
this.worldSeeds.removeIf(worldSeed -> {
|
||||||
FakeBiomeSource fakeBiomeSource = new FakeBiomeSource(worldSeed);
|
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||||
return !biomeData.test(fakeBiomeSource);
|
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[1];
|
||||||
|
return !biomeData.test(worldSeed, sampler);
|
||||||
});
|
});
|
||||||
} else if(this.worldSeeds != null) {
|
} else if(this.worldSeeds != null) {
|
||||||
this.worldSeeds.removeIf(worldSeed -> {
|
this.worldSeeds.removeIf(worldSeed -> {
|
||||||
for(BiomeData data: this.biomeCache) {
|
for(BiomeData data: this.biomeCache) {
|
||||||
FakeBiomeSource fakeBiomeSource = new FakeBiomeSource(worldSeed);
|
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||||
if(!data.test(fakeBiomeSource))return true;
|
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[1];
|
||||||
|
if(!biomeData.test(worldSeed, sampler))return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -228,7 +292,6 @@ public class SeedCracker implements ModInitializer {
|
|||||||
writer.close();*/
|
writer.close();*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
private static List<ChunkPos> initialize(long worldSeed) {
|
private static List<ChunkPos> initialize(long worldSeed) {
|
||||||
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||||
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[0];
|
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[0];
|
||||||
@@ -265,10 +328,8 @@ public class SeedCracker implements ModInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return startPositions;
|
return startPositions;
|
||||||
}./
|
}
|
||||||
|
|
||||||
//CHECK NEW 1.15 SAMPLER
|
|
||||||
/*
|
|
||||||
public static BlockPos locateBiome(BiomeLayerSampler sampler, int x, int z, int size, List<Biome> validBiomes, Random rand) {
|
public static BlockPos locateBiome(BiomeLayerSampler sampler, int x, int z, int size, List<Biome> validBiomes, Random rand) {
|
||||||
int int_4 = x - size >> 2;
|
int int_4 = x - size >> 2;
|
||||||
int int_5 = z - size >> 2;
|
int int_5 = z - size >> 2;
|
||||||
@@ -293,6 +354,6 @@ public class SeedCracker implements ModInitializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return pos;
|
return pos;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package kaptainwutax.seedcracker.cracker;
|
|||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.source.VoronoiBiomeAccessType;
|
import net.minecraft.world.biome.layer.BiomeLayerSampler;
|
||||||
|
|
||||||
public class BiomeData {
|
public class BiomeData {
|
||||||
|
|
||||||
@@ -25,20 +25,8 @@ public class BiomeData {
|
|||||||
this(x, z, Registry.BIOME.get(biomeId));
|
this(x, z, Registry.BIOME.get(biomeId));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean test(FakeBiomeSource source) {
|
public boolean test(long worldSeed, BiomeLayerSampler sampler) {
|
||||||
return VoronoiBiomeAccessType.INSTANCE.getBiome(source.getHashedSeed(), this.x,0, this.z, source) == this.biome;
|
return sampler.sample(this.x, this.z) == this.biome;
|
||||||
}
|
|
||||||
|
|
||||||
public int getX() {
|
|
||||||
return this.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getZ() {
|
|
||||||
return this.z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Biome getBiome() {
|
|
||||||
return this.biome;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class DecoratorCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeBiomeStep(Biome biome, GenerationStep.Feature genStep) {
|
private void initializeBiomeStep(Biome biome, GenerationStep.Feature genStep) {
|
||||||
List<ConfiguredFeature<?, ?>> features = biome.getFeaturesForStep(genStep);
|
List<ConfiguredFeature<?>> features = biome.getFeaturesForStep(genStep);
|
||||||
|
|
||||||
for(int i = 0; i < features.size(); i++) {
|
for(int i = 0; i < features.size(); i++) {
|
||||||
FeatureConfig config = features.get(i).config;
|
FeatureConfig config = features.get(i).config;
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
package kaptainwutax.seedcracker.cracker;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import net.minecraft.world.biome.Biome;
|
|
||||||
import net.minecraft.world.biome.Biomes;
|
|
||||||
import net.minecraft.world.biome.layer.BiomeLayers;
|
|
||||||
import net.minecraft.world.biome.source.BiomeLayerSampler;
|
|
||||||
import net.minecraft.world.biome.source.BiomeSource;
|
|
||||||
import net.minecraft.world.gen.chunk.OverworldChunkGeneratorConfig;
|
|
||||||
import net.minecraft.world.level.LevelGeneratorType;
|
|
||||||
import net.minecraft.world.level.LevelProperties;
|
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class FakeBiomeSource extends BiomeSource {
|
|
||||||
|
|
||||||
public static final OverworldChunkGeneratorConfig CHUNK_GEN_CONFIG = new OverworldChunkGeneratorConfig();
|
|
||||||
|
|
||||||
private static final Set<Biome> BIOMES;
|
|
||||||
private final BiomeLayerSampler biomeSampler;
|
|
||||||
|
|
||||||
private long seed;
|
|
||||||
private long hashedSeed;
|
|
||||||
|
|
||||||
public FakeBiomeSource(long worldSeed) {
|
|
||||||
super(BIOMES);
|
|
||||||
this.seed = worldSeed;
|
|
||||||
this.hashedSeed = LevelProperties.sha256Hash(worldSeed);
|
|
||||||
this.biomeSampler = BiomeLayers.build(this.seed, LevelGeneratorType.DEFAULT, CHUNK_GEN_CONFIG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
|
||||||
return this.biomeSampler.sample(biomeX, biomeZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getSeed() {
|
|
||||||
return this.seed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getHashedSeed() {
|
|
||||||
return this.hashedSeed;
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
BIOMES = ImmutableSet.<Biome>of(Biomes.OCEAN, Biomes.PLAINS, Biomes.DESERT, Biomes.MOUNTAINS, Biomes.FOREST, Biomes.TAIGA, Biomes.SWAMP, Biomes.RIVER, Biomes.FROZEN_OCEAN, Biomes.FROZEN_RIVER, Biomes.SNOWY_TUNDRA, Biomes.SNOWY_MOUNTAINS, Biomes.MUSHROOM_FIELDS, Biomes.MUSHROOM_FIELD_SHORE, Biomes.BEACH, Biomes.DESERT_HILLS, Biomes.WOODED_HILLS, Biomes.TAIGA_HILLS, Biomes.MOUNTAIN_EDGE, Biomes.JUNGLE, Biomes.JUNGLE_HILLS, Biomes.JUNGLE_EDGE, Biomes.DEEP_OCEAN, Biomes.STONE_SHORE, Biomes.SNOWY_BEACH, Biomes.BIRCH_FOREST, Biomes.BIRCH_FOREST_HILLS, Biomes.DARK_FOREST, Biomes.SNOWY_TAIGA, Biomes.SNOWY_TAIGA_HILLS, Biomes.GIANT_TREE_TAIGA, Biomes.GIANT_TREE_TAIGA_HILLS, Biomes.WOODED_MOUNTAINS, Biomes.SAVANNA, Biomes.SAVANNA_PLATEAU, Biomes.BADLANDS, Biomes.WOODED_BADLANDS_PLATEAU, Biomes.BADLANDS_PLATEAU, Biomes.WARM_OCEAN, Biomes.LUKEWARM_OCEAN, Biomes.COLD_OCEAN, Biomes.DEEP_WARM_OCEAN, Biomes.DEEP_LUKEWARM_OCEAN, Biomes.DEEP_COLD_OCEAN, Biomes.DEEP_FROZEN_OCEAN, Biomes.SUNFLOWER_PLAINS, Biomes.DESERT_LAKES, Biomes.GRAVELLY_MOUNTAINS, Biomes.FLOWER_FOREST, Biomes.TAIGA_MOUNTAINS, Biomes.SWAMP_HILLS, Biomes.ICE_SPIKES, Biomes.MODIFIED_JUNGLE, Biomes.MODIFIED_JUNGLE_EDGE, Biomes.TALL_BIRCH_FOREST, Biomes.TALL_BIRCH_HILLS, Biomes.DARK_FOREST_HILLS, Biomes.SNOWY_TAIGA_MOUNTAINS, Biomes.GIANT_SPRUCE_TAIGA, Biomes.GIANT_SPRUCE_TAIGA_HILLS, Biomes.MODIFIED_GRAVELLY_MOUNTAINS, Biomes.SHATTERED_SAVANNA, Biomes.SHATTERED_SAVANNA_PLATEAU, Biomes.ERODED_BADLANDS, Biomes.MODIFIED_WOODED_BADLANDS_PLATEAU, Biomes.MODIFIED_BADLANDS_PLATEAU);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -9,11 +9,11 @@ public class StructureData {
|
|||||||
private int regionZ;
|
private int regionZ;
|
||||||
private int offsetX;
|
private int offsetX;
|
||||||
private int offsetZ;
|
private int offsetZ;
|
||||||
private FeatureType featureType;
|
private Feature feature;
|
||||||
|
|
||||||
public StructureData(ChunkPos chunkPos, FeatureType featureType) {
|
public StructureData(ChunkPos chunkPos, Feature feature) {
|
||||||
this.featureType = featureType;
|
this.feature = feature;
|
||||||
this.featureType.build(this, chunkPos);
|
this.feature.build(this, chunkPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegionX() {
|
public int getRegionX() {
|
||||||
@@ -33,15 +33,15 @@ public class StructureData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getSalt() {
|
public int getSalt() {
|
||||||
return this.featureType.salt;
|
return this.feature.salt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FeatureType getFeatureType() {
|
public Feature getFeature() {
|
||||||
return this.featureType;
|
return this.feature;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean test(ChunkRandom rand) {
|
public boolean test(ChunkRandom rand) {
|
||||||
return this.featureType.test(rand, this.offsetX, this.offsetZ);
|
return this.feature.test(rand, this.offsetX, this.offsetZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -50,17 +50,17 @@ public class StructureData {
|
|||||||
|
|
||||||
if(obj instanceof StructureData) {
|
if(obj instanceof StructureData) {
|
||||||
StructureData structureData = ((StructureData)obj);
|
StructureData structureData = ((StructureData)obj);
|
||||||
return structureData.regionX == this.regionX && structureData.regionZ == this.regionZ && structureData.featureType == this.featureType;
|
return structureData.regionX == this.regionX && structureData.regionZ == this.regionZ && structureData.feature == this.feature;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class FeatureType {
|
public abstract static class Feature {
|
||||||
public final int salt;
|
public final int salt;
|
||||||
public final int distance;
|
public final int distance;
|
||||||
|
|
||||||
public FeatureType(int salt, int distance) {
|
public Feature(int salt, int distance) {
|
||||||
this.salt = salt;
|
this.salt = salt;
|
||||||
this.distance = distance;
|
this.distance = distance;
|
||||||
}
|
}
|
||||||
@@ -89,56 +89,56 @@ public class StructureData {
|
|||||||
public abstract boolean test(ChunkRandom rand, int x, int z);
|
public abstract boolean test(ChunkRandom rand, int x, int z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final FeatureType DESERT_PYRAMID = new FeatureType(14357617, 32) {
|
public static final Feature DESERT_PYRAMID = new Feature(14357617, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType IGLOO = new FeatureType(14357618, 32) {
|
public static final Feature IGLOO = new Feature(14357618, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType JUNGLE_TEMPLE = new FeatureType(14357619, 32) {
|
public static final Feature JUNGLE_TEMPLE = new Feature(14357619, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType SWAMP_HUT = new FeatureType(14357620, 32) {
|
public static final Feature SWAMP_HUT = new Feature(14357620, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType OCEAN_RUIN = new FeatureType(14357621, 16) {
|
public static final Feature OCEAN_RUIN = new Feature(14357621, 16) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(8) == x && rand.nextInt(8) == z;
|
return rand.nextInt(8) == x && rand.nextInt(8) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType SHIPWRECK = new FeatureType(165745295, 16) {
|
public static final Feature SHIPWRECK = new Feature(165745295, 16) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(8) == x && rand.nextInt(8) == z;
|
return rand.nextInt(8) == x && rand.nextInt(8) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType PILLAGER_OUTPOST = new FeatureType(165745296, 32) {
|
public static final Feature PILLAGER_OUTPOST = new Feature(165745296, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
return rand.nextInt(24) == x && rand.nextInt(24) == z;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType END_CITY = new FeatureType(10387313, 20) {
|
public static final Feature END_CITY = new Feature(10387313, 20) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return (rand.nextInt(9) + rand.nextInt(9)) / 2 == x
|
return (rand.nextInt(9) + rand.nextInt(9)) / 2 == x
|
||||||
@@ -146,7 +146,7 @@ public class StructureData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType OCEAN_MONUMENT = new FeatureType(10387313, 32) {
|
public static final Feature OCEAN_MONUMENT = new Feature(10387313, 32) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return (rand.nextInt(27) + rand.nextInt(27)) / 2 == x
|
return (rand.nextInt(27) + rand.nextInt(27)) / 2 == x
|
||||||
@@ -154,14 +154,14 @@ public class StructureData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType BURIED_TREASURE = new FeatureType(10387320, 1) {
|
public static final Feature BURIED_TREASURE = new Feature(10387320, 1) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return rand.nextFloat() < 0.01f;
|
return rand.nextFloat() < 0.1f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final FeatureType WOODLAND_MANSION = new FeatureType(10387319, 80) {
|
public static final Feature WOODLAND_MANSION = new Feature(10387319, 80) {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ChunkRandom rand, int x, int z) {
|
public boolean test(ChunkRandom rand, int x, int z) {
|
||||||
return (rand.nextInt(60) + rand.nextInt(60)) / 2 == x
|
return (rand.nextInt(60) + rand.nextInt(60)) / 2 == x
|
||||||
|
|||||||
@@ -1,38 +1,30 @@
|
|||||||
package kaptainwutax.seedcracker.cracker;
|
package kaptainwutax.seedcracker.cracker;
|
||||||
|
|
||||||
import kaptainwutax.seedcracker.cracker.population.DecoratorData;
|
import kaptainwutax.seedcracker.SeedCracker;
|
||||||
|
import kaptainwutax.seedcracker.cracker.population.PopulationData;
|
||||||
import kaptainwutax.seedcracker.util.Log;
|
import kaptainwutax.seedcracker.util.Log;
|
||||||
import kaptainwutax.seedcracker.util.Rand;
|
import kaptainwutax.seedcracker.util.Rand;
|
||||||
import kaptainwutax.seedcracker.util.math.LCG;
|
import kaptainwutax.seedcracker.util.math.LCG;
|
||||||
import net.minecraft.world.gen.ChunkRandom;
|
import net.minecraft.world.gen.ChunkRandom;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
public class TimeMachine {
|
public class TimeMachine {
|
||||||
|
|
||||||
private LCG inverseLCG = Rand.JAVA_LCG.combine(-2);
|
private LCG inverseLCG = Rand.JAVA_LCG.combine(-2);
|
||||||
public int THREAD_COUNT = 4;
|
|
||||||
public ExecutorService SERVICE = Executors.newFixedThreadPool(THREAD_COUNT);
|
|
||||||
|
|
||||||
private boolean isRunning = false;
|
|
||||||
|
|
||||||
public TimeMachine() {
|
public TimeMachine() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Long> bruteforceRegion(int pillarSeed, int region, long size, List<StructureData> structureDataList, List<DecoratorData> decoratorDataList) {
|
public List<Long> buildStructureSeeds(int pillarSeed, List<StructureData> structureDataList, List<PopulationData> populationDataList, List<Long> structureSeeds) {
|
||||||
List<Long> result = new ArrayList<>();
|
|
||||||
ChunkRandom chunkRandom = new ChunkRandom();
|
ChunkRandom chunkRandom = new ChunkRandom();
|
||||||
|
|
||||||
long start = region * size;
|
for(long i = 0; i < (1L << 32); i++) {
|
||||||
long end = start + size;
|
if((i & ((1L << 28) - 1)) == 0) {
|
||||||
|
Log.warn("Progress " + (i * 100.0f) / (1L << 32) + "%...");
|
||||||
|
}
|
||||||
|
|
||||||
for(long i = start; i < end; i++) {
|
|
||||||
long structureSeed = this.timeMachine(i, pillarSeed);
|
long structureSeed = this.timeMachine(i, pillarSeed);
|
||||||
boolean goodSeed = true;
|
boolean goodSeed = true;
|
||||||
|
|
||||||
@@ -43,44 +35,16 @@ public class TimeMachine {
|
|||||||
if(!structureData.test(chunkRandom))goodSeed = false;
|
if(!structureData.test(chunkRandom))goodSeed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(DecoratorData decoratorData : decoratorDataList) {
|
for(PopulationData populationData: populationDataList) {
|
||||||
if(!goodSeed)break;
|
if(!goodSeed)break;
|
||||||
if(!decoratorData.test(structureSeed))goodSeed = false;
|
if(!populationData.test(structureSeed))goodSeed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(goodSeed) {
|
if(goodSeed) {
|
||||||
result.add(structureSeed);
|
structureSeeds.add(structureSeed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Set<Long> buildStructureSeeds(int pillarSeed, List<StructureData> structureDataList, List<DecoratorData> decoratorDataList, Set<Long> structureSeeds) {
|
|
||||||
if(this.isRunning) {
|
|
||||||
throw new IllegalStateException("Time Machine is already running");
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isRunning = true;
|
|
||||||
long size = (long)Math.ceil((double)(1L << 32) / THREAD_COUNT);
|
|
||||||
AtomicInteger progress = new AtomicInteger();
|
|
||||||
|
|
||||||
for(int i = 0; i < THREAD_COUNT; i++) {
|
|
||||||
int finalI = i;
|
|
||||||
|
|
||||||
SERVICE.submit(() -> {
|
|
||||||
structureSeeds.addAll(this.bruteforceRegion(pillarSeed, finalI, size, structureDataList, decoratorDataList));
|
|
||||||
Log.warn("Completed thread " + finalI + "!");
|
|
||||||
progress.getAndIncrement();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
while(progress.get() < THREAD_COUNT) {
|
|
||||||
try {Thread.sleep(20);}
|
|
||||||
catch(InterruptedException e) {e.printStackTrace();}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isRunning = false;
|
|
||||||
return structureSeeds;
|
return structureSeeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,8 +59,4 @@ public class TimeMachine {
|
|||||||
return currentSeed;
|
return currentSeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
this.isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import net.minecraft.world.gen.decorator.Decorator;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DungeonData extends DecoratorData {
|
public class DungeonData extends PopulationData {
|
||||||
|
|
||||||
public static LCG REVERSE_SKIP = Rand.JAVA_LCG.combine(-1);
|
public static LCG REVERSE_SKIP = Rand.JAVA_LCG.combine(-1);
|
||||||
public static LCG Y_START_SKIP = Rand.JAVA_LCG.combine(2);
|
public static LCG Y_START_SKIP = Rand.JAVA_LCG.combine(2);
|
||||||
@@ -30,25 +30,31 @@ public class DungeonData extends DecoratorData {
|
|||||||
@Override
|
@Override
|
||||||
public boolean testDecorator(long decoratorSeed) {
|
public boolean testDecorator(long decoratorSeed) {
|
||||||
if(this.starts.isEmpty())return true;
|
if(this.starts.isEmpty())return true;
|
||||||
Rand rand = new Rand(decoratorSeed, false);
|
|
||||||
|
|
||||||
//TODO: This currently only supports 1 dungeon per chunk.
|
//TODO: This currently only supports 1 dungeon per chunk.
|
||||||
BlockPos start = this.starts.get(0);
|
BlockPos start = this.starts.get(0);
|
||||||
|
|
||||||
|
long currentSeed = decoratorSeed;
|
||||||
|
boolean valid = false;
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
int x = rand.nextInt(16);
|
currentSeed = i == 0 ? Y_START_SKIP.nextSeed(currentSeed) : Y_SKIP.nextSeed(currentSeed);
|
||||||
int z = rand.nextInt(16);
|
|
||||||
int y = rand.nextInt(256);
|
|
||||||
|
|
||||||
if(y == start.getY() && x == start.getX() && z == start.getZ()) {
|
if(currentSeed >> 40 == start.getY()) {
|
||||||
return true;
|
valid = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rand.nextInt(2);
|
|
||||||
rand.nextInt(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if(!valid)return false;
|
||||||
|
|
||||||
|
int x = (int)(REVERSE_SKIP.nextSeed(currentSeed) >> 44);
|
||||||
|
if(x != start.getX())return false;
|
||||||
|
|
||||||
|
int z = (int)(Rand.JAVA_LCG.nextSeed(currentSeed) >> 44);
|
||||||
|
if(z != start.getZ())return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import net.minecraft.world.gen.decorator.Decorator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class EmeraldOreData extends DecoratorData {
|
public class EmeraldOreData extends PopulationData {
|
||||||
|
|
||||||
public static final LCG[] SKIP = {
|
public static final LCG[] SKIP = {
|
||||||
Rand.JAVA_LCG.combine(0),
|
Rand.JAVA_LCG.combine(0),
|
||||||
@@ -41,8 +41,8 @@ public class EmeraldOreData extends DecoratorData {
|
|||||||
|
|
||||||
for(int i = 0; i < b + 3; i++) {
|
for(int i = 0; i < b + 3; i++) {
|
||||||
int x = rand.nextInt(16);
|
int x = rand.nextInt(16);
|
||||||
int z = rand.nextInt(16);
|
|
||||||
int y = rand.nextInt(28) + 4;
|
int y = rand.nextInt(28) + 4;
|
||||||
|
int z = rand.nextInt(16);
|
||||||
|
|
||||||
if(y == start.getY() && x == start.getX() && z == start.getZ()) {
|
if(y == start.getY() && x == start.getX() && z == start.getZ()) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import net.minecraft.util.math.ChunkPos;
|
|||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.gen.decorator.Decorator;
|
import net.minecraft.world.gen.decorator.Decorator;
|
||||||
|
|
||||||
public class EndGatewayData extends DecoratorData {
|
public class EndGatewayData extends PopulationData {
|
||||||
|
|
||||||
private int xOffset;
|
private int xOffset;
|
||||||
private int zOffset;
|
private int zOffset;
|
||||||
|
|||||||
+7
-7
@@ -16,13 +16,13 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class DecoratorData {
|
public abstract class PopulationData {
|
||||||
|
|
||||||
private final ChunkPos chunkPos;
|
private final ChunkPos chunkPos;
|
||||||
private final Decorator<?> decorator;
|
private final Decorator<?> decorator;
|
||||||
private final Biome biome;
|
private final Biome biome;
|
||||||
|
|
||||||
public DecoratorData(ChunkPos chunkPos, Decorator<?> decorator, Biome biome) {
|
public PopulationData(ChunkPos chunkPos, Decorator<?> decorator, Biome biome) {
|
||||||
this.chunkPos = chunkPos;
|
this.chunkPos = chunkPos;
|
||||||
this.decorator = decorator;
|
this.decorator = decorator;
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
@@ -55,9 +55,9 @@ public abstract class DecoratorData {
|
|||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if(obj == this)return true;
|
if(obj == this)return true;
|
||||||
|
|
||||||
if(obj instanceof DecoratorData) {
|
if(obj instanceof PopulationData) {
|
||||||
DecoratorData decoratorData = ((DecoratorData)obj);
|
PopulationData populationData = ((PopulationData)obj);
|
||||||
return decoratorData.chunkPos.equals(this.chunkPos) && decoratorData.decorator == this.decorator;
|
return populationData.chunkPos.equals(this.chunkPos) && populationData.decorator == this.decorator;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -80,10 +80,10 @@ public abstract class DecoratorData {
|
|||||||
return new ChunkRandom(CACHE.get(biome));
|
return new ChunkRandom(CACHE.get(biome));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ConfiguredFeature<?, ?>> features = biome.getFeaturesForStep(this.genStep);
|
List<ConfiguredFeature<?>> features = biome.getFeaturesForStep(this.genStep);
|
||||||
|
|
||||||
for(int i = 0; i < features.size(); i++) {
|
for(int i = 0; i < features.size(); i++) {
|
||||||
ConfiguredFeature<?, ?> feature = features.get(i);
|
ConfiguredFeature<?> feature = features.get(i);
|
||||||
if(!(feature.config instanceof DecoratedFeatureConfig))continue;
|
if(!(feature.config instanceof DecoratedFeatureConfig))continue;
|
||||||
ConfiguredDecorator<?> currentDecorator = ((DecoratedFeatureConfig)feature.config).decorator;
|
ConfiguredDecorator<?> currentDecorator = ((DecoratedFeatureConfig)feature.config).decorator;
|
||||||
|
|
||||||
@@ -9,7 +9,6 @@ import net.minecraft.util.math.ChunkPos;
|
|||||||
import net.minecraft.world.Heightmap;
|
import net.minecraft.world.Heightmap;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.biome.Biome;
|
import net.minecraft.world.biome.Biome;
|
||||||
import net.minecraft.world.biome.Biomes;
|
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -30,11 +29,6 @@ public class BiomeFinder extends Finder {
|
|||||||
BlockPos blockPos = this.chunkPos.getCenterBlockPos().add(x, 0, z);
|
BlockPos blockPos = this.chunkPos.getCenterBlockPos().add(x, 0, z);
|
||||||
Biome biome = this.world.getBiome(blockPos);
|
Biome biome = this.world.getBiome(blockPos);
|
||||||
|
|
||||||
//TODO: Fix this multi-threading issue.
|
|
||||||
if(biome == Biomes.THE_VOID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(SeedCracker.get().onBiomeData(new BiomeData(blockPos.getX(), blockPos.getZ(), biome))) {
|
if(SeedCracker.get().onBiomeData(new BiomeData(blockPos.getX(), blockPos.getZ(), biome))) {
|
||||||
blockPos = this.world.getTopPosition(Heightmap.Type.WORLD_SURFACE, blockPos).down();
|
blockPos = this.world.getTopPosition(Heightmap.Type.WORLD_SURFACE, blockPos).down();
|
||||||
result.add(blockPos);
|
result.add(blockPos);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public abstract class BlockFinder extends Finder {
|
|||||||
|
|
||||||
public BlockFinder(World world, ChunkPos chunkPos, Block block) {
|
public BlockFinder(World world, ChunkPos chunkPos, Block block) {
|
||||||
super(world, chunkPos);
|
super(world, chunkPos);
|
||||||
this.targetBlockStates.addAll(block.getStateManager().getStates());
|
this.targetBlockStates.addAll(block.getStateFactory().getStates());
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockFinder(World world, ChunkPos chunkPos, BlockState... blockStates) {
|
public BlockFinder(World world, ChunkPos chunkPos, BlockState... blockStates) {
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ public abstract class Finder {
|
|||||||
|
|
||||||
static {
|
static {
|
||||||
for(int x = 0; x < 16; x++) {
|
for(int x = 0; x < 16; x++) {
|
||||||
for(int z = 0; z < 16; z++) {
|
for(int y = 0; y < 256; y++) {
|
||||||
for(int y = 0; y < 256; y++) {
|
for(int z = 0; z < 16; z++) {
|
||||||
|
|
||||||
BlockPos pos = new BlockPos(x, y, z);
|
BlockPos pos = new BlockPos(x, y, z);
|
||||||
if(y < 16)SUB_CHUNK_POSITIONS.add(pos);
|
if(y < 16)SUB_CHUNK_POSITIONS.add(pos);
|
||||||
CHUNK_POSITIONS.add(pos);
|
CHUNK_POSITIONS.add(pos);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package kaptainwutax.seedcracker.finder;
|
package kaptainwutax.seedcracker.finder;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
@@ -42,11 +40,7 @@ public class FinderQueue {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderFinders(MatrixStack matrixStack) {
|
public void renderFinders() {
|
||||||
RenderSystem.pushMatrix();
|
|
||||||
RenderSystem.multMatrix(matrixStack.peek().getModel());
|
|
||||||
|
|
||||||
//System.out.println("rendering");
|
|
||||||
if(this.renderType == RenderType.OFF)return;
|
if(this.renderType == RenderType.OFF)return;
|
||||||
|
|
||||||
GlStateManager.disableTexture();
|
GlStateManager.disableTexture();
|
||||||
@@ -62,7 +56,11 @@ public class FinderQueue {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
RenderSystem.popMatrix();
|
GlStateManager.enableTexture();
|
||||||
|
|
||||||
|
if(this.renderType == RenderType.XRAY) {
|
||||||
|
GlStateManager.enableDepthTest();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clear() {
|
public void clear() {
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public class DungeonFinder extends BlockFinder {
|
|||||||
.map(pos -> this.getFloorCalls(this.getDungeonSize(pos), pos)).collect(Collectors.toList());
|
.map(pos -> this.getFloorCalls(this.getDungeonSize(pos), pos)).collect(Collectors.toList());
|
||||||
|
|
||||||
result.forEach(pos -> {
|
result.forEach(pos -> {
|
||||||
if(SeedCracker.get().onDecoratorData(new DungeonData(this.chunkPos, biome, starts, floorCallsList))) {
|
if(SeedCracker.get().onPopulationData(new DungeonData(this.chunkPos, biome, starts, floorCallsList))) {
|
||||||
this.renderers.add(new Cube(pos, new Vector4f(1.0f, 0.0f, 0.0f, 1.0f)));
|
this.renderers.add(new Cube(pos, new Vector4f(1.0f, 0.0f, 0.0f, 1.0f)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class EndGatewayFinder extends BlockFinder {
|
|||||||
if(height >= 3 && height <= 9) {
|
if(height >= 3 && height <= 9) {
|
||||||
newResult.add(pos);
|
newResult.add(pos);
|
||||||
|
|
||||||
if(SeedCracker.get().onDecoratorData(new EndGatewayData(this.chunkPos, biome, pos, height))) {
|
if(SeedCracker.get().onPopulationData(new EndGatewayData(this.chunkPos, biome, pos, height))) {
|
||||||
this.renderers.add(new Cuboid(pos.add(-1, -2, -1), pos.add(2, 3, 2), new Vector4f(0.4f, 0.4f, 0.82f, 1.0f)));
|
this.renderers.add(new Cuboid(pos.add(-1, -2, -1), pos.add(2, 3, 2), new Vector4f(0.4f, 0.4f, 0.82f, 1.0f)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class EmeraldOreFinder extends BlockFinder {
|
|||||||
|
|
||||||
List<BlockPos> result = super.findInChunk();
|
List<BlockPos> result = super.findInChunk();
|
||||||
|
|
||||||
if(!result.isEmpty() && SeedCracker.get().onDecoratorData(new EmeraldOreData(this.chunkPos, biome, result))) {
|
if(!result.isEmpty() && SeedCracker.get().onPopulationData(new EmeraldOreData(this.chunkPos, biome, result))) {
|
||||||
result.forEach(pos -> {
|
result.forEach(pos -> {
|
||||||
this.renderers.add(new Cube(pos, new Vector4f(0.0f, 1.0f, 0.0f, 1.0f)));
|
this.renderers.add(new Cube(pos, new Vector4f(0.0f, 1.0f, 0.0f, 1.0f)));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import java.util.Map;
|
|||||||
public class PieceFinder extends Finder {
|
public class PieceFinder extends Finder {
|
||||||
|
|
||||||
protected Map<BlockPos, BlockState> structure = new LinkedHashMap<>();
|
protected Map<BlockPos, BlockState> structure = new LinkedHashMap<>();
|
||||||
private BlockBox boundingBox;
|
private MutableIntBoundingBox boundingBox;
|
||||||
protected List<BlockPos> searchPositions = new ArrayList<>();
|
protected List<BlockPos> searchPositions = new ArrayList<>();
|
||||||
|
|
||||||
protected Direction facing;
|
protected Direction facing;
|
||||||
@@ -40,12 +40,12 @@ public class PieceFinder extends Finder {
|
|||||||
this.depth = size.getZ();
|
this.depth = size.getZ();
|
||||||
|
|
||||||
if(this.facing.getAxis() == Direction.Axis.Z) {
|
if(this.facing.getAxis() == Direction.Axis.Z) {
|
||||||
this.boundingBox = new BlockBox(
|
this.boundingBox = new MutableIntBoundingBox(
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
size.getX() - 1, size.getY() - 1, size.getZ() - 1
|
size.getX() - 1, size.getY() - 1, size.getZ() - 1
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
this.boundingBox = new BlockBox(
|
this.boundingBox = new MutableIntBoundingBox(
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
size.getZ() - 1, size.getY() - 1, size.getX() - 1
|
size.getZ() - 1, size.getY() - 1, size.getX() - 1
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package kaptainwutax.seedcracker.mixin;
|
package kaptainwutax.seedcracker.mixin;
|
||||||
|
|
||||||
import kaptainwutax.seedcracker.SeedCracker;
|
|
||||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||||
|
import kaptainwutax.seedcracker.SeedCracker;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.world.biome.Biome;
|
|
||||||
import net.minecraft.world.biome.Biomes;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
@Mixin(ClientWorld.class)
|
@Mixin(ClientWorld.class)
|
||||||
public abstract class ClientWorldMixin {
|
public abstract class ClientWorldMixin {
|
||||||
@@ -18,11 +17,8 @@ public abstract class ClientWorldMixin {
|
|||||||
private void disconnect(CallbackInfo ci) {
|
private void disconnect(CallbackInfo ci) {
|
||||||
SeedCracker.get().clear();
|
SeedCracker.get().clear();
|
||||||
FinderQueue.get().clear();
|
FinderQueue.get().clear();
|
||||||
}
|
FinderQueue.SERVICE.shutdown();
|
||||||
|
FinderQueue.SERVICE = Executors.newFixedThreadPool(5);
|
||||||
@Inject(method = "getGeneratorStoredBiome", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void getGeneratorStoredBiome(int x, int y, int z, CallbackInfoReturnable<Biome> ci) {
|
|
||||||
ci.setReturnValue(Biomes.THE_VOID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package kaptainwutax.seedcracker.mixin;
|
|||||||
|
|
||||||
import kaptainwutax.seedcracker.render.RenderQueue;
|
import kaptainwutax.seedcracker.render.RenderQueue;
|
||||||
import net.minecraft.client.render.GameRenderer;
|
import net.minecraft.client.render.GameRenderer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
@@ -11,14 +10,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin(GameRenderer.class)
|
@Mixin(GameRenderer.class)
|
||||||
public abstract class GameRendererMixin {
|
public abstract class GameRendererMixin {
|
||||||
|
|
||||||
@Inject(method = "renderWorld", at = @At("HEAD"))
|
@Inject(method = "renderCenter", at = @At("HEAD"))
|
||||||
private void renderWorldStart(float delta, long time, MatrixStack matrixStack, CallbackInfo ci) {
|
private void renderCenterStart(float delta, long time, CallbackInfo ci) {
|
||||||
RenderQueue.get().setTrackRender(matrixStack);
|
RenderQueue.get().setTrackRender(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "renderWorld", at = @At("TAIL"))
|
@Inject(method = "renderCenter", at = @At("TAIL"))
|
||||||
private void renderWorldFinish(float delta, long time, MatrixStack matrixStack, CallbackInfo ci) {
|
private void renderCenterFinish(float delta, long time, CallbackInfo ci) {
|
||||||
RenderQueue.get().setTrackRender(null);
|
RenderQueue.get().setTrackRender(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class Line extends Renderer {
|
|||||||
|
|
||||||
Vec3d camPos = this.mc.gameRenderer.getCamera().getPos();
|
Vec3d camPos = this.mc.gameRenderer.getCamera().getPos();
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
BufferBuilder buffer = tessellator.getBufferBuilder();
|
||||||
|
|
||||||
//This is how thick the line is.
|
//This is how thick the line is.
|
||||||
GlStateManager.lineWidth(2.0f);
|
GlStateManager.lineWidth(2.0f);
|
||||||
@@ -48,16 +48,18 @@ public class Line extends Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void putVertex(BufferBuilder buffer, Vec3d camPos, Vec3d pos) {
|
protected void putVertex(BufferBuilder buffer, Vec3d camPos, Vec3d pos) {
|
||||||
buffer.vertex(
|
for(int i = 0; i < 2; i++) {
|
||||||
pos.getX() - camPos.x,
|
buffer.vertex(
|
||||||
pos.getY() - camPos.y,
|
pos.getX() - camPos.x,
|
||||||
pos.getZ() - camPos.z
|
pos.getY() - camPos.y,
|
||||||
).color(
|
pos.getZ() - camPos.z
|
||||||
this.color.getX(),
|
).color(
|
||||||
this.color.getY(),
|
this.color.getX(),
|
||||||
this.color.getZ(),
|
this.color.getY(),
|
||||||
this.color.getW()
|
this.color.getZ(),
|
||||||
).next();
|
this.color.getW()
|
||||||
|
).next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,19 @@
|
|||||||
package kaptainwutax.seedcracker.render;
|
package kaptainwutax.seedcracker.render;
|
||||||
|
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
public class RenderQueue {
|
public class RenderQueue {
|
||||||
|
|
||||||
private final static RenderQueue INSTANCE = new RenderQueue();
|
private final static RenderQueue INSTANCE = new RenderQueue();
|
||||||
|
|
||||||
private Map<String, List<Consumer<MatrixStack>>> typeRunnableMap = new HashMap<>();
|
private Map<String, List<Runnable>> typeRunnableMap = new HashMap<>();
|
||||||
private MatrixStack matrixStack = null;
|
private boolean trackRender = false;
|
||||||
|
|
||||||
public static RenderQueue get() {
|
public static RenderQueue get() {
|
||||||
return INSTANCE;
|
return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(String type, Consumer<MatrixStack> runnable) {
|
public void add(String type, Runnable runnable) {
|
||||||
Objects.requireNonNull(type);
|
Objects.requireNonNull(type);
|
||||||
Objects.requireNonNull(runnable);
|
Objects.requireNonNull(runnable);
|
||||||
|
|
||||||
@@ -24,11 +21,11 @@ public class RenderQueue {
|
|||||||
this.typeRunnableMap.put(type, new ArrayList<>());
|
this.typeRunnableMap.put(type, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Consumer<MatrixStack>> runnableList = this.typeRunnableMap.get(type);
|
List<Runnable> runnableList = this.typeRunnableMap.get(type);
|
||||||
runnableList.add(runnable);
|
runnableList.add(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(String type, Consumer<MatrixStack> runnable) {
|
public void remove(String type, Runnable runnable) {
|
||||||
Objects.requireNonNull(type);
|
Objects.requireNonNull(type);
|
||||||
Objects.requireNonNull(runnable);
|
Objects.requireNonNull(runnable);
|
||||||
|
|
||||||
@@ -36,17 +33,17 @@ public class RenderQueue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Consumer<MatrixStack>> runnableList = this.typeRunnableMap.get(type);
|
List<Runnable> runnableList = this.typeRunnableMap.get(type);
|
||||||
runnableList.remove(runnable);
|
runnableList.remove(runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrackRender(MatrixStack matrixStack) {
|
public void setTrackRender(boolean flag) {
|
||||||
this.matrixStack = matrixStack;
|
this.trackRender = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRender(String type) {
|
public void onRender(String type) {
|
||||||
if(this.matrixStack == null || !this.typeRunnableMap.containsKey(type))return;
|
if(!this.trackRender || !this.typeRunnableMap.containsKey(type))return;
|
||||||
this.typeRunnableMap.get(type).forEach(r -> r.accept(this.matrixStack));
|
this.typeRunnableMap.get(type).forEach(Runnable::run);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
package kaptainwutax.seedcracker.util;
|
package kaptainwutax.seedcracker.util;
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.util.TextFormat;
|
import net.minecraft.client.util.TextComponentUtil;
|
||||||
|
import net.minecraft.text.Texts;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.text.LiteralText;
|
import net.minecraft.text.LiteralText;
|
||||||
|
|
||||||
|
import static net.minecraft.util.Formatting.RED;
|
||||||
|
import static net.minecraft.util.Formatting.YELLOW;
|
||||||
|
|
||||||
public class Log {
|
public class Log {
|
||||||
|
|
||||||
public static void debug(String message) {
|
public static void debug(String message) {
|
||||||
@@ -19,7 +23,7 @@ public class Log {
|
|||||||
PlayerEntity player = getPlayer();
|
PlayerEntity player = getPlayer();
|
||||||
|
|
||||||
if(player != null) {
|
if(player != null) {
|
||||||
player.addChatMessage(new LiteralText(TextFormat.YELLOW + message), false);
|
player.addChatMessage(new LiteralText(YELLOW + message), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +31,7 @@ public class Log {
|
|||||||
PlayerEntity player = getPlayer();
|
PlayerEntity player = getPlayer();
|
||||||
|
|
||||||
if(player != null) {
|
if(player != null) {
|
||||||
player.addChatMessage(new LiteralText(TextFormat.RED + message), false);
|
player.addChatMessage(new LiteralText(RED + message), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,12 @@ public class PosIterator {
|
|||||||
Set<BlockPos> result = new HashSet<>();
|
Set<BlockPos> result = new HashSet<>();
|
||||||
|
|
||||||
for(int x = start.getX(); x <= end.getX(); x++) {
|
for(int x = start.getX(); x <= end.getX(); x++) {
|
||||||
for(int z = start.getZ(); z <= end.getZ(); z++) {
|
|
||||||
for(int y = start.getY(); y <= end.getY(); y++) {
|
for(int y = start.getY(); y <= end.getY(); y++) {
|
||||||
result.add(new BlockPos(x, y, z));
|
for(int z = start.getZ(); z <= end.getZ(); z++) {
|
||||||
|
result.add(new BlockPos(x, y, z));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user