various additions
This commit is contained in:
+3
-3
@@ -4,8 +4,8 @@ org.gradle.jvmargs=-Xmx1G
|
||||
# Fabric Properties
|
||||
# check these on https://fabricmc.net/use
|
||||
minecraft_version=1.14.4
|
||||
yarn_mappings=1.14.4+build.12
|
||||
loader_version=0.6.2+build.166
|
||||
yarn_mappings=1.14.4+build.15
|
||||
loader_version=0.7.2+build.174
|
||||
|
||||
# Mod Properties
|
||||
mod_version = 1.0.0
|
||||
@@ -14,4 +14,4 @@ org.gradle.jvmargs=-Xmx1G
|
||||
|
||||
# Dependencies
|
||||
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
|
||||
fabric_version=0.3.2+build.218-1.14
|
||||
fabric_version=0.4.1+build.245-1.14
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
package kaptainwutax.seedcracker;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import io.netty.util.internal.ConcurrentSet;
|
||||
import kaptainwutax.seedcracker.finder.*;
|
||||
import kaptainwutax.seedcracker.util.FinderBuilder;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class FinderQueue {
|
||||
|
||||
private final static FinderQueue INSTANCE = new FinderQueue();
|
||||
public static final ExecutorService SERVICE = Executors.newFixedThreadPool(5);
|
||||
|
||||
public RenderType renderType = RenderType.XRAY;
|
||||
private List<FinderBuilder> finderBuilders = new ArrayList<>();
|
||||
private Set<Finder> activeFinders = new ConcurrentSet<>();
|
||||
|
||||
private FinderQueue() {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
public static FinderQueue get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void onChunkData(World world, ChunkPos chunkPos) {
|
||||
this.finderBuilders.forEach(finderBuilder -> {
|
||||
SERVICE.submit(() -> {
|
||||
List<Finder> finders = finderBuilder.build(world, chunkPos);
|
||||
|
||||
finders.forEach(finder -> {
|
||||
if (finder.isValidDimension(finder.getWorld().dimension.getType())) {
|
||||
finder.findInChunk();
|
||||
if(!finder.isUseless()) {
|
||||
this.activeFinders.add(finder);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void renderFinders() {
|
||||
if(this.renderType == RenderType.OFF)return;
|
||||
|
||||
GlStateManager.disableTexture();
|
||||
|
||||
//Makes it render through blocks.
|
||||
if(this.renderType == RenderType.XRAY) {
|
||||
GlStateManager.disableDepthTest();
|
||||
}
|
||||
|
||||
this.activeFinders.forEach(finder -> {
|
||||
if(finder.shouldRender()) {
|
||||
finder.render();
|
||||
}
|
||||
});
|
||||
|
||||
GlStateManager.enableTexture();
|
||||
|
||||
if(this.renderType == RenderType.XRAY) {
|
||||
GlStateManager.enableDepthTest();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.activeFinders.clear();
|
||||
this.finderBuilders.clear();
|
||||
|
||||
this.finderBuilders.add(DungeonFinder::create);
|
||||
this.finderBuilders.add(BuriedTreasureFinder::create);
|
||||
this.finderBuilders.add(SwampHutFinder::create);
|
||||
this.finderBuilders.add(DesertTempleFinder::create);
|
||||
this.finderBuilders.add(JungleTempleFinder::create);
|
||||
this.finderBuilders.add(EndPillarsFinder::create);
|
||||
this.finderBuilders.add(BiomeFinder::create);
|
||||
this.finderBuilders.add(OceanMonumentFinder::create);
|
||||
this.finderBuilders.add(EndCityFinder::create);
|
||||
this.finderBuilders.add(IglooFinder::create);
|
||||
|
||||
//this.finderBuilders.add(DiamondOreFinder::create);
|
||||
//this.finderBuilders.add(InfestedStoneOreFinder::create);
|
||||
}
|
||||
|
||||
public enum RenderType {
|
||||
OFF, ON, XRAY
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,21 +1,31 @@
|
||||
package kaptainwutax.seedcracker;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import kaptainwutax.seedcracker.cracker.*;
|
||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||
import kaptainwutax.seedcracker.render.RenderQueue;
|
||||
import kaptainwutax.seedcracker.util.Rand;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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.feature.Feature;
|
||||
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.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class SeedCracker implements ModInitializer {
|
||||
|
||||
@@ -31,9 +41,54 @@ public class SeedCracker implements ModInitializer {
|
||||
private List<PopulationData> populationCache = new ArrayList<>();
|
||||
private List<BiomeData> biomeCache = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
RenderQueue.get().add("hand", FinderQueue.get()::renderFinders);
|
||||
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) {
|
||||
StrongholdFeature.Start start = new StrongholdFeature.Start(Feature.STRONGHOLD, pos.x, pos.z, Biomes.PLAINS, MutableIntBoundingBox.empty(), 0, worldSeed);
|
||||
}
|
||||
|
||||
public static SeedCracker get() {
|
||||
@@ -46,6 +101,7 @@ public class SeedCracker implements ModInitializer {
|
||||
this.pillarSeeds = null;
|
||||
this.structureCache.clear();
|
||||
this.biomeCache.clear();
|
||||
this.populationCache.clear();
|
||||
}
|
||||
|
||||
public synchronized boolean onPillarData(PillarData pillarData) {
|
||||
@@ -75,12 +131,13 @@ public class SeedCracker implements ModInitializer {
|
||||
added = true;
|
||||
}
|
||||
|
||||
if(this.structureSeeds == null && this.pillarSeeds != null && this.structureCache.size() >= 3) {
|
||||
if(this.structureSeeds == null && this.pillarSeeds != null && this.structureCache.size() + this.populationCache.size() >= 5) {
|
||||
this.structureSeeds = new ArrayList<>();
|
||||
LOG.warn("Looking for structure seeds with " + this.structureCache.size() + " structure features.");
|
||||
LOG.warn("Looking for structure seeds with " + this.populationCache.size() + " population features.");
|
||||
|
||||
this.pillarSeeds.forEach(pillarSeed -> {
|
||||
timeMachine.buildStructureSeeds(pillarSeed, this.structureCache, this.structureSeeds);
|
||||
timeMachine.buildStructureSeeds(pillarSeed, this.structureCache, this.populationCache, this.structureSeeds);
|
||||
});
|
||||
|
||||
if(this.structureSeeds.size() > 0) {
|
||||
@@ -113,37 +170,7 @@ public class SeedCracker implements ModInitializer {
|
||||
added = true;
|
||||
}
|
||||
|
||||
if(this.worldSeeds == null && this.structureSeeds != null && this.populationCache.size() >= 4) {
|
||||
this.worldSeeds = new ArrayList<>();
|
||||
LOG.warn("Looking for world seeds with " + this.populationCache.size() + " decorators.");
|
||||
|
||||
for(int i = 0; i < this.structureSeeds.size(); i++) {
|
||||
SeedCracker.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;
|
||||
boolean goodSeed = true;
|
||||
|
||||
for(PopulationData data: this.populationCache) {
|
||||
if(!data.test(worldSeed)) {
|
||||
goodSeed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(goodSeed) {
|
||||
this.worldSeeds.add(worldSeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOG.warn("Finished search with " + this.worldSeeds + (this.worldSeeds.size() == 1 ? " seed." : " seeds."));
|
||||
} else if(this.worldSeeds != null && populationData != null) {
|
||||
this.worldSeeds.removeIf(worldSeed -> !populationData.test(worldSeed));
|
||||
}
|
||||
|
||||
this.onStructureData(null);
|
||||
return added;
|
||||
}
|
||||
|
||||
@@ -209,8 +236,13 @@ public class SeedCracker implements ModInitializer {
|
||||
return added;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Random rand = new Random(1234L);
|
||||
public static void main(String[] args) throws Exception {
|
||||
for(int i = 0; i < 10000; i++) {
|
||||
Rand rand = new Rand(i, false);
|
||||
if(rand.nextInt(700) == 0)System.out.println(i);
|
||||
}
|
||||
|
||||
/*Random rand = new Random(1234L);
|
||||
|
||||
IntStream.range(0, 8).mapToObj((int_1x) -> {
|
||||
int int_2 = rand.nextInt(16);
|
||||
@@ -220,7 +252,100 @@ public class SeedCracker implements ModInitializer {
|
||||
return new BlockPos(int_2, int_3, int_4);
|
||||
}).forEach(pos -> {
|
||||
System.out.println("Populating " + pos);
|
||||
});
|
||||
});*/
|
||||
|
||||
/*
|
||||
System.out.println(validSeed(65867021031296932L));
|
||||
|
||||
BufferedReader reader = new BufferedReader(new FileReader("run/seeds.txt"));
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter("run/kaktoos14.txt"));
|
||||
|
||||
while(reader.ready()) {
|
||||
long seed = Long.parseLong(reader.readLine().split(Pattern.quote(" "))[0]);
|
||||
seed ^= Rand.JAVA_LCG.multiplier;
|
||||
seed -= 60007;
|
||||
|
||||
writer.write(seed + "===========================================\n");
|
||||
|
||||
for(int i = 0; i < (1 << 16); i++) {
|
||||
long worldSeed = seed | ((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();*/
|
||||
}
|
||||
|
||||
private static List<ChunkPos> initialize(long worldSeed) {
|
||||
BiomeLayerSampler sampler = BiomeLayers.build(worldSeed, LevelGeneratorType.DEFAULT,
|
||||
BiomeSourceType.VANILLA_LAYERED.getConfig().getGeneratorSettings())[0];
|
||||
|
||||
List<ChunkPos> startPositions = new ArrayList<>();
|
||||
List<Biome> validBiomes = Lists.newArrayList();
|
||||
Iterator biomeIterator = Registry.BIOME.iterator();
|
||||
|
||||
while(biomeIterator.hasNext()) {
|
||||
Biome biome = (Biome)biomeIterator.next();
|
||||
if(biome != null && biome.hasStructureFeature(Feature.STRONGHOLD)) {
|
||||
validBiomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
Random rand = new Random(worldSeed);
|
||||
double randomRadian = rand.nextDouble() * Math.PI * 2.0D;
|
||||
|
||||
//Actually 128, but we don't care about all of them.
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
double double_2 = 128.0D + (rand.nextDouble() - 0.5D) * 80.0D;
|
||||
int x = (int)Math.round(Math.cos(randomRadian) * double_2);
|
||||
int z = (int)Math.round(Math.sin(randomRadian) * double_2);
|
||||
|
||||
BlockPos locatedPos = locateBiome(sampler, (x << 4) + 8, (z << 4) + 8, 112, validBiomes, rand);
|
||||
|
||||
if(locatedPos != null) {
|
||||
x = locatedPos.getX() >> 4;
|
||||
z = locatedPos.getZ() >> 4;
|
||||
}
|
||||
|
||||
startPositions.add(new ChunkPos(x, z));
|
||||
randomRadian += (Math.PI * 2.0D) / 3.0d;
|
||||
}
|
||||
|
||||
return startPositions;
|
||||
}
|
||||
|
||||
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_5 = z - size >> 2;
|
||||
int int_6 = x + size >> 2;
|
||||
int int_7 = z + size >> 2;
|
||||
int int_8 = int_6 - int_4 + 1;
|
||||
int int_9 = int_7 - int_5 + 1;
|
||||
Biome[] biomeSample = sampler.sample(int_4, int_5, int_8, int_9);
|
||||
BlockPos pos = null;
|
||||
int int_10 = 0;
|
||||
|
||||
for(int i = 0; i < int_8 * int_9; ++i) {
|
||||
int int_12 = int_4 + i % int_8 << 2;
|
||||
int int_13 = int_5 + i / int_8 << 2;
|
||||
if (validBiomes.contains(biomeSample[i])) {
|
||||
if(pos == null || rand.nextInt(int_10 + 1) == 0) {
|
||||
pos = new BlockPos(int_12, 0, int_13);
|
||||
}
|
||||
|
||||
++int_10;
|
||||
}
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,10 +2,10 @@ package kaptainwutax.seedcracker.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import kaptainwutax.seedcracker.ClientCommands;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.util.Formatting;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
@@ -16,7 +16,7 @@ public abstract class ClientCommand {
|
||||
public abstract void build(LiteralArgumentBuilder<ServerCommandSource> builder);
|
||||
|
||||
protected final void sendFeedback(String message, boolean overlay) {
|
||||
MinecraftClient.getInstance().player.addChatMessage(new LiteralText(message), overlay);
|
||||
MinecraftClient.getInstance().player.addChatMessage(new LiteralText(message).formatted(Formatting.AQUA), overlay);
|
||||
}
|
||||
|
||||
public final void register(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
|
||||
+8
-8
@@ -1,10 +1,8 @@
|
||||
package kaptainwutax.seedcracker;
|
||||
package kaptainwutax.seedcracker.command;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import kaptainwutax.seedcracker.command.ClientCommand;
|
||||
import kaptainwutax.seedcracker.command.RenderCommand;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.command.CommandException;
|
||||
@@ -21,21 +19,23 @@ public class ClientCommands {
|
||||
public static final List<ClientCommand> COMMANDS = new ArrayList<>();
|
||||
|
||||
public static RenderCommand RENDER;
|
||||
public static FinderCommand FINDER;
|
||||
|
||||
static {
|
||||
COMMANDS.add(RENDER = new RenderCommand());
|
||||
COMMANDS.add(FINDER = new FinderCommand());
|
||||
}
|
||||
|
||||
public static void registerCommands(CommandDispatcher<ServerCommandSource> dispatcher) {
|
||||
COMMANDS.forEach(clientCommand -> clientCommand.register(dispatcher));
|
||||
}
|
||||
|
||||
public static boolean isClientSideCommand(String[] params) {
|
||||
if(params.length < 2)return false;
|
||||
if(!PREFIX.equals(params[0]))return false;
|
||||
public static boolean isClientSideCommand(String[] args) {
|
||||
if(args.length < 2)return false;
|
||||
if(!PREFIX.equals(args[0]))return false;
|
||||
|
||||
for(ClientCommand command: COMMANDS) {
|
||||
if(command.getName().equals(params[1])) {
|
||||
if(command.getName().equals(args[1])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public class ClientCommands {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shoutout to Earthcomputer for this awesome class.
|
||||
* Magic class by Earthcomputer.
|
||||
* https://github.com/Earthcomputer/clientcommands/blob/fabric/src/main/java/net/earthcomputer/clientcommands/command/FakeCommandSource.java
|
||||
* */
|
||||
public static class FakeCommandSource extends ServerCommandSource {
|
||||
@@ -0,0 +1,59 @@
|
||||
package kaptainwutax.seedcracker.command;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import kaptainwutax.seedcracker.finder.FinderConfig;
|
||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
|
||||
public class FinderCommand extends ClientCommand {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "finder";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void build(LiteralArgumentBuilder<ServerCommandSource> builder) {
|
||||
for(FinderConfig.Type finderType: FinderConfig.Type.values()) {
|
||||
builder.then(literal("type")
|
||||
.executes(context -> this.printFinderType(finderType))
|
||||
.then(literal(finderType.toString())
|
||||
.then(literal("ON").executes(context -> this.setFinderType(finderType, true)))
|
||||
.then(literal("OFF").executes(context -> this.setFinderType(finderType, false))))
|
||||
);
|
||||
}
|
||||
|
||||
for(FinderConfig.Category finderCategory: FinderConfig.Category.values()) {
|
||||
builder.then(literal("category")
|
||||
.executes(context -> this.printFinderCategory(finderCategory))
|
||||
.then(literal(finderCategory.toString())
|
||||
.then(literal("ON").executes(context -> this.setFinderCategory(finderCategory, true)))
|
||||
.then(literal("OFF").executes(context -> this.setFinderCategory(finderCategory, false))))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private int printFinderCategory(FinderConfig.Category finderCategory) {
|
||||
FinderConfig.Type.getForCategory(finderCategory).forEach(this::printFinderType);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int printFinderType(FinderConfig.Type finderType) {
|
||||
this.sendFeedback("Finder " + finderType + " is set to [" + String.valueOf(FinderQueue.get().finderConfig.getTypeState(finderType)).toUpperCase() + "].", false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int setFinderCategory(FinderConfig.Category finderCategory, boolean flag) {
|
||||
FinderConfig.Type.getForCategory(finderCategory).forEach(finderType -> this.setFinderType(finderType, flag));
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int setFinderType(FinderConfig.Type finderType, boolean flag) {
|
||||
FinderQueue.get().finderConfig.setTypeState(finderType, flag);
|
||||
this.sendFeedback("Finder " + finderType + " has been set to [" + String.valueOf(flag).toUpperCase() + "].", false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package kaptainwutax.seedcracker.command;
|
||||
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import kaptainwutax.seedcracker.FinderQueue;
|
||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
|
||||
import static net.minecraft.server.command.CommandManager.literal;
|
||||
@@ -17,10 +17,13 @@ public class RenderCommand extends ClientCommand {
|
||||
public void build(LiteralArgumentBuilder<ServerCommandSource> builder) {
|
||||
builder.then(literal("outlines")
|
||||
.executes(context -> this.printRenderMode())
|
||||
.then(literal("XRAY").executes(context -> this.setRenderMode(FinderQueue.RenderType.XRAY)))
|
||||
.then(literal("ON").executes(context -> this.setRenderMode(FinderQueue.RenderType.ON)))
|
||||
.then(literal("OFF").executes(context -> this.setRenderMode(FinderQueue.RenderType.OFF)))
|
||||
);
|
||||
|
||||
for(FinderQueue.RenderType renderType: FinderQueue.RenderType.values()) {
|
||||
builder.then(literal("outlines")
|
||||
.then(literal(renderType.toString()).executes(context -> this.setRenderMode(renderType)))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private int printRenderMode() {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package kaptainwutax.seedcracker.cracker;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.FeatureConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DecoratorCache {
|
||||
|
||||
public static int INVALID = -1;
|
||||
|
||||
private static DecoratorCache INSTANCE = new DecoratorCache();
|
||||
private boolean initialized = false;
|
||||
|
||||
private Map<Biome, Map<Decorator<?>, Integer>> decoratorSaltMap = new HashMap<>();
|
||||
|
||||
public static DecoratorCache get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void initialize() {
|
||||
Registry.BIOME.forEach(biome -> {
|
||||
this.decoratorSaltMap.put(biome, new HashMap<>());
|
||||
|
||||
for(GenerationStep.Feature genStep: GenerationStep.Feature.values()) {
|
||||
this.initializeBiomeStep(biome, genStep);
|
||||
}
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
private void initializeBiomeStep(Biome biome, GenerationStep.Feature genStep) {
|
||||
List<ConfiguredFeature<?>> features = biome.getFeaturesForStep(genStep);
|
||||
|
||||
for(int i = 0; i < features.size(); i++) {
|
||||
FeatureConfig config = features.get(i).config;
|
||||
if(!(config instanceof DecoratedFeatureConfig))continue;
|
||||
this.decoratorSaltMap.get(biome).put(((DecoratedFeatureConfig)config).decorator.decorator, i + genStep.ordinal() * 10000);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSalt(Biome biome, Decorator<?> feature, boolean debug) {
|
||||
if(!this.initialized) {
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
Integer salt = this.decoratorSaltMap.get(biome).get(feature);
|
||||
|
||||
if(salt == null) {
|
||||
if(debug) {
|
||||
SeedCracker.LOG.warn(biome.getClass().getSimpleName() + " does not have decorator " + feature + ".");
|
||||
}
|
||||
|
||||
salt = INVALID;
|
||||
}
|
||||
|
||||
return salt;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
package kaptainwutax.seedcracker.cracker;
|
||||
|
||||
import kaptainwutax.seedcracker.util.Rand;
|
||||
import kaptainwutax.seedcracker.util.math.LCG;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.ChunkRandom;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DungeonData extends PopulationData {
|
||||
|
||||
public static final Feature DUNGEON = new Feature(GenerationStep.Feature.UNDERGROUND_STRUCTURES, Decorator.DUNGEONS) {};
|
||||
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_SKIP = Rand.JAVA_LCG.combine(5);
|
||||
|
||||
public static final Integer COBBLESTONE_CALL = 0;
|
||||
public static final Integer MOSSY_COBBLESTONE_CALL = 1;
|
||||
|
||||
@@ -20,28 +22,37 @@ public class DungeonData extends PopulationData {
|
||||
private final List<List<Integer>> floorCallsList;
|
||||
|
||||
public DungeonData(ChunkPos chunkPos, Biome biome, List<BlockPos> starts, List<List<Integer>> floorCallsList) {
|
||||
super(chunkPos, DUNGEON, biome);
|
||||
super(chunkPos, Decorator.DUNGEONS, biome);
|
||||
this.starts = starts;
|
||||
this.floorCallsList = floorCallsList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(ChunkRandom chunkRandom) {
|
||||
List<Integer> idsToCheck = new ArrayList<>();
|
||||
public boolean testDecorator(long decoratorSeed) {
|
||||
if(this.starts.isEmpty())return false;
|
||||
|
||||
//TODO: This currently only supports 1 dungeon per chunk.
|
||||
BlockPos start = this.starts.get(0);
|
||||
|
||||
long currentSeed = decoratorSeed;
|
||||
boolean valid = false;
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
BlockPos pos = new BlockPos(chunkRandom.nextInt(16), chunkRandom.nextInt(256), chunkRandom.nextInt(16));
|
||||
int a = this.starts.indexOf(pos);
|
||||
if(a != -1)idsToCheck.add(a);
|
||||
currentSeed = i == 0 ? Y_START_SKIP.nextSeed(currentSeed) : Y_SKIP.nextSeed(currentSeed);
|
||||
|
||||
//We assume the dungeon failed, skip 2 calls.
|
||||
chunkRandom.nextBoolean();
|
||||
chunkRandom.nextBoolean();
|
||||
if(currentSeed >> 40 == start.getY()) {
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(idsToCheck.size() != this.starts.size())return false;
|
||||
if(!valid)return false;
|
||||
|
||||
//TODO: Implement floor calls.
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package kaptainwutax.seedcracker.cracker;
|
||||
|
||||
import kaptainwutax.seedcracker.util.Rand;
|
||||
import kaptainwutax.seedcracker.util.math.LCG;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EmeraldOreData extends PopulationData {
|
||||
|
||||
public static final LCG[] SKIP = {
|
||||
Rand.JAVA_LCG.combine(0),
|
||||
Rand.JAVA_LCG.combine(1),
|
||||
Rand.JAVA_LCG.combine(2),
|
||||
Rand.JAVA_LCG.combine(3)
|
||||
};
|
||||
|
||||
private List<BlockPos> starts;
|
||||
|
||||
public EmeraldOreData(ChunkPos chunkPos, Biome biome, List<BlockPos> ores) {
|
||||
super(chunkPos, Decorator.EMERALD_ORE, biome);
|
||||
|
||||
this.starts = ores.stream().map(pos -> {
|
||||
return new BlockPos(pos.getX() & 15, pos.getY(), pos.getZ() & 15);
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testDecorator(long decoratorSeed) {
|
||||
if(this.starts.isEmpty())return false;
|
||||
|
||||
//TODO: This currently only supports 1 emerald per chunk.
|
||||
BlockPos start = this.starts.get(0);
|
||||
|
||||
Rand rand = new Rand(decoratorSeed, false);
|
||||
int b = rand.nextInt(6);
|
||||
|
||||
for(int i = 0; i < b; i++) {
|
||||
int x = rand.nextInt(16);
|
||||
int y = rand.nextInt(28) + 4;
|
||||
int z = rand.nextInt(16);
|
||||
|
||||
if(x == start.getX() && y == start.getY() && z == start.getZ()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package kaptainwutax.seedcracker.cracker;
|
||||
|
||||
import kaptainwutax.seedcracker.util.Rand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
|
||||
public class EndGatewayData extends PopulationData {
|
||||
|
||||
private int xOffset;
|
||||
private int zOffset;
|
||||
private int height;
|
||||
|
||||
public EndGatewayData(ChunkPos chunkPos, Biome biome, BlockPos pos, int height) {
|
||||
super(chunkPos, Decorator.END_GATEWAY, biome);
|
||||
this.xOffset = pos.getX() & 15;
|
||||
this.zOffset = pos.getZ() & 15;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean testDecorator(long decoratorSeed) {
|
||||
Rand rand = new Rand(decoratorSeed, false);
|
||||
|
||||
if(rand.nextInt(700) != 0)return false;
|
||||
if(rand.nextInt(16) != this.xOffset)return false;
|
||||
if(rand.nextInt(16) != this.zOffset)return false;
|
||||
if(rand.nextInt(7) != this.height - 3)return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package kaptainwutax.seedcracker.cracker;
|
||||
|
||||
import kaptainwutax.seedcracker.util.Rand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
@@ -10,26 +11,44 @@ import net.minecraft.world.gen.decorator.Decorator;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class PopulationData {
|
||||
|
||||
private final ChunkPos chunkPos;
|
||||
private final Feature feature;
|
||||
private final Decorator<?> decorator;
|
||||
private final Biome biome;
|
||||
|
||||
public PopulationData(ChunkPos chunkPos, Feature feature, Biome biome) {
|
||||
public PopulationData(ChunkPos chunkPos, Decorator<?> decorator, Biome biome) {
|
||||
this.chunkPos = chunkPos;
|
||||
this.feature = feature;
|
||||
this.decorator = decorator;
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
public final boolean test(long worldSeed) {
|
||||
ChunkRandom chunkRandom = this.feature.buildRand(worldSeed, this.biome, this.chunkPos);
|
||||
return this.test(chunkRandom);
|
||||
public final boolean test(long structureSeed) {
|
||||
long decoratorSeed = this.getPopulationSeed(structureSeed, this.chunkPos.x << 4, this.chunkPos.z << 4);
|
||||
int salt = DecoratorCache.get().getSalt(this.biome, this.decorator, true);
|
||||
|
||||
if(salt == DecoratorCache.INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
decoratorSeed += salt;
|
||||
decoratorSeed ^= Rand.JAVA_LCG.multiplier;
|
||||
decoratorSeed &= Rand.JAVA_LCG.modulo - 1;
|
||||
return this.testDecorator(decoratorSeed);
|
||||
}
|
||||
|
||||
public abstract boolean test(ChunkRandom chunkRandom);
|
||||
public long getPopulationSeed(long structureSeed, int x, int z) {
|
||||
Rand rand = new Rand(structureSeed, true);
|
||||
long a = rand.nextLong() | 1L;
|
||||
long b = rand.nextLong() | 1L;
|
||||
return (long)x * a + (long)z * b ^ structureSeed;
|
||||
}
|
||||
|
||||
public abstract boolean testDecorator(long decoratorSeed);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@@ -37,7 +56,7 @@ public abstract class PopulationData {
|
||||
|
||||
if(obj instanceof PopulationData) {
|
||||
PopulationData populationData = ((PopulationData)obj);
|
||||
return populationData.chunkPos.equals(this.chunkPos) && populationData.feature == this.feature;
|
||||
return populationData.chunkPos.equals(this.chunkPos) && populationData.decorator == this.decorator;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -45,6 +64,8 @@ public abstract class PopulationData {
|
||||
|
||||
|
||||
public abstract static class Feature {
|
||||
private Map<Biome, Long> CACHE = new HashMap<>();
|
||||
|
||||
private GenerationStep.Feature genStep;
|
||||
private Decorator decorator;
|
||||
|
||||
@@ -54,6 +75,10 @@ public abstract class PopulationData {
|
||||
}
|
||||
|
||||
public ChunkRandom buildRand(long worldSeed, Biome biome, ChunkPos chunkPos) {
|
||||
if(CACHE.containsKey(biome)) {
|
||||
return new ChunkRandom(CACHE.get(biome));
|
||||
}
|
||||
|
||||
List<ConfiguredFeature<?>> features = biome.getFeaturesForStep(this.genStep);
|
||||
|
||||
for(int i = 0; i < features.size(); i++) {
|
||||
@@ -65,7 +90,8 @@ public abstract class PopulationData {
|
||||
BlockPos pos = new BlockPos(chunkPos.getStartX(), 0, chunkPos.getStartZ());
|
||||
ChunkRandom chunkRandom = new ChunkRandom();
|
||||
long populationSeed = chunkRandom.setSeed(worldSeed, pos.getX(), pos.getZ());
|
||||
chunkRandom.setFeatureSeed(populationSeed, i, this.genStep.ordinal());
|
||||
long seed = chunkRandom.setFeatureSeed(populationSeed, i, this.genStep.ordinal());
|
||||
CACHE.put(biome, seed ^ Rand.JAVA_LCG.multiplier);
|
||||
return chunkRandom;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import kaptainwutax.seedcracker.util.math.LCG;
|
||||
import net.minecraft.world.gen.ChunkRandom;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class TimeMachine {
|
||||
|
||||
@@ -16,7 +15,7 @@ public class TimeMachine {
|
||||
|
||||
}
|
||||
|
||||
public List<Long> buildStructureSeeds(int pillarSeed, List<StructureData> structureDataList, List<Long> structureSeeds) {
|
||||
public List<Long> buildStructureSeeds(int pillarSeed, List<StructureData> structureDataList, List<PopulationData> populationDataList, List<Long> structureSeeds) {
|
||||
ChunkRandom chunkRandom = new ChunkRandom();
|
||||
|
||||
for(long i = 0; i < (1L << 32); i++) {
|
||||
@@ -28,13 +27,15 @@ public class TimeMachine {
|
||||
boolean goodSeed = true;
|
||||
|
||||
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(chunkRandom)) {
|
||||
goodSeed = false;
|
||||
break;
|
||||
}
|
||||
for(PopulationData populationData: populationDataList) {
|
||||
if(!goodSeed)break;
|
||||
if(!populationData.test(structureSeed))goodSeed = false;
|
||||
}
|
||||
|
||||
if(goodSeed) {
|
||||
|
||||
@@ -37,7 +37,7 @@ public class BiomeFinder extends Finder {
|
||||
}
|
||||
|
||||
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.05f, 0.2f, 0.125f, 1.0f)));
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
|
||||
public class DefaultFinderConfig extends FinderConfig {
|
||||
|
||||
public DefaultFinderConfig() {
|
||||
super();
|
||||
this.typeStates.put(Type.DIAMOND_ORE, false);
|
||||
this.typeStates.put(Type.INFESTED_STONE_ORE, false);
|
||||
this.typeStates.put(Type.IGLOO, false);
|
||||
this.typeStates.put(Type.MANSION, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
|
||||
import kaptainwutax.seedcracker.finder.population.DungeonFinder;
|
||||
import kaptainwutax.seedcracker.finder.population.EndGatewayFinder;
|
||||
import kaptainwutax.seedcracker.finder.population.EndPillarsFinder;
|
||||
import kaptainwutax.seedcracker.finder.population.ore.DiamondOreFinder;
|
||||
import kaptainwutax.seedcracker.finder.population.ore.EmeraldOreFinder;
|
||||
import kaptainwutax.seedcracker.finder.population.ore.InfestedStoneOreFinder;
|
||||
import kaptainwutax.seedcracker.finder.structure.*;
|
||||
import kaptainwutax.seedcracker.util.FinderBuilder;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FinderConfig {
|
||||
|
||||
protected Map<Type, Boolean> typeStates = new HashMap<>();
|
||||
protected Map<Type, ConcurrentLinkedQueue<Finder>> activeFinders = new ConcurrentHashMap<>();
|
||||
|
||||
public FinderConfig() {
|
||||
for(Type type: Type.values()) {
|
||||
this.typeStates.put(type, true);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Type> getActiveFinderTypes() {
|
||||
return this.typeStates.entrySet().stream()
|
||||
.filter(Map.Entry::getValue)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<Finder> getActiveFinders() {
|
||||
this.activeFinders.values().forEach(finders -> {
|
||||
finders.removeIf(Finder::isUseless);
|
||||
});
|
||||
|
||||
return this.activeFinders.values().stream()
|
||||
.flatMap(Queue::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void addFinder(Type type, Finder finder) {
|
||||
if(finder.isUseless())return;
|
||||
|
||||
if(!this.activeFinders.containsKey(type)) {
|
||||
this.activeFinders.put(type, new ConcurrentLinkedQueue<>());
|
||||
}
|
||||
|
||||
this.activeFinders.get(type).add(finder);
|
||||
}
|
||||
|
||||
public boolean getTypeState(Type type) {
|
||||
return this.typeStates.get(type);
|
||||
}
|
||||
|
||||
public void setTypeState(Type type, boolean flag) {
|
||||
this.typeStates.put(type, flag);
|
||||
}
|
||||
|
||||
public enum Category {
|
||||
STRUCTURES,
|
||||
BIOMES,
|
||||
ORES,
|
||||
OTHERS
|
||||
}
|
||||
|
||||
public enum Type {
|
||||
BURIED_TREASURE(BuriedTreasureFinder::create, Category.STRUCTURES),
|
||||
DESERT_TEMPLE(DesertTempleFinder::create, Category.STRUCTURES),
|
||||
END_CITY(EndCityFinder::create, Category.STRUCTURES),
|
||||
IGLOO(IglooFinder::create, Category.STRUCTURES),
|
||||
JUNGLE_TEMPLE(JungleTempleFinder::create, Category.STRUCTURES),
|
||||
MONUMENT(OceanMonumentFinder::create, Category.STRUCTURES),
|
||||
SWAMP_HUT(SwampHutFinder::create, Category.STRUCTURES),
|
||||
MANSION(MansionFinder::create, Category.STRUCTURES),
|
||||
|
||||
END_PILLARS(EndPillarsFinder::create, Category.OTHERS),
|
||||
END_GATEWAY(EndGatewayFinder::create, Category.OTHERS),
|
||||
DUNGEON(DungeonFinder::create, Category.OTHERS),
|
||||
DIAMOND_ORE(DiamondOreFinder::create, Category.ORES),
|
||||
INFESTED_STONE_ORE(InfestedStoneOreFinder::create, Category.ORES),
|
||||
EMERALD_ORE(EmeraldOreFinder::create, Category.ORES),
|
||||
|
||||
BIOME(BiomeFinder::create, Category.BIOMES);
|
||||
|
||||
public final FinderBuilder finderBuilder;
|
||||
private final Category category;
|
||||
|
||||
Type(FinderBuilder finderBuilder, Category category) {
|
||||
this.finderBuilder = finderBuilder;
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public static List<Type> getForCategory(Category category) {
|
||||
return Arrays.stream(values()).filter(type -> type.category == category).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class FinderQueue {
|
||||
|
||||
private final static FinderQueue INSTANCE = new FinderQueue();
|
||||
public static ExecutorService SERVICE = Executors.newFixedThreadPool(5);
|
||||
|
||||
public RenderType renderType = RenderType.XRAY;
|
||||
public FinderConfig finderConfig = new DefaultFinderConfig();
|
||||
|
||||
private FinderQueue() {
|
||||
this.clear();
|
||||
}
|
||||
|
||||
public static FinderQueue get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void onChunkData(World world, ChunkPos chunkPos) {
|
||||
this.finderConfig.getActiveFinderTypes().forEach(type -> {
|
||||
SERVICE.submit(() -> {
|
||||
List<Finder> finders = type.finderBuilder.build(world, chunkPos);
|
||||
|
||||
finders.forEach(finder -> {
|
||||
if(finder.isValidDimension(world.dimension.getType())) {
|
||||
this.finderConfig.addFinder(type, finder);
|
||||
finder.findInChunk();
|
||||
this.finderConfig.addFinder(type, finder);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void renderFinders() {
|
||||
if(this.renderType == RenderType.OFF)return;
|
||||
|
||||
GlStateManager.disableTexture();
|
||||
|
||||
//Makes it render through blocks.
|
||||
if(this.renderType == RenderType.XRAY) {
|
||||
GlStateManager.disableDepthTest();
|
||||
}
|
||||
|
||||
this.finderConfig.getActiveFinders().forEach(finder -> {
|
||||
if(finder.shouldRender()) {
|
||||
finder.render();
|
||||
}
|
||||
});
|
||||
|
||||
GlStateManager.enableTexture();
|
||||
|
||||
if(this.renderType == RenderType.XRAY) {
|
||||
GlStateManager.enableDepthTest();
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.renderType = RenderType.XRAY;
|
||||
this.finderConfig = new DefaultFinderConfig();
|
||||
}
|
||||
|
||||
public enum RenderType {
|
||||
OFF, ON, XRAY
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -1,7 +1,9 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.population;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.DungeonData;
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.util.PosIterator;
|
||||
import net.minecraft.block.Block;
|
||||
@@ -0,0 +1,91 @@
|
||||
package kaptainwutax.seedcracker.finder.population;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.DecoratorCache;
|
||||
import kaptainwutax.seedcracker.cracker.EndGatewayData;
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EndGatewayFinder extends BlockFinder {
|
||||
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = buildSearchPositions(CHUNK_POSITIONS, pos -> {
|
||||
return false;
|
||||
});
|
||||
|
||||
public EndGatewayFinder(World world, ChunkPos chunkPos) {
|
||||
super(world, chunkPos, Blocks.END_GATEWAY);
|
||||
this.searchPositions = SEARCH_POSITIONS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> findInChunk() {
|
||||
//If no end gateway is supposed to populate in this chunk, return.
|
||||
Biome biome = this.world.getBiome(this.chunkPos.getCenterBlockPos().add(8, 0, 8));
|
||||
|
||||
if(DecoratorCache.get().getSalt(biome, Decorator.END_GATEWAY, false) == DecoratorCache.INVALID) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<BlockPos> result = super.findInChunk();
|
||||
List<BlockPos> newResult = new ArrayList<>();
|
||||
|
||||
result.forEach(pos -> {
|
||||
int height = this.findHeight(pos);
|
||||
|
||||
if(height >= 3 && height <= 9) {
|
||||
newResult.add(pos);
|
||||
System.out.println("Height is " + 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)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return newResult;
|
||||
}
|
||||
|
||||
private int findHeight(BlockPos pos) {
|
||||
int height = 0;
|
||||
|
||||
while(pos.getY() >= 0) {
|
||||
pos = pos.down();
|
||||
height++;
|
||||
|
||||
BlockState state = this.world.getBlockState(pos);
|
||||
|
||||
//Bedrock generates below gateways.
|
||||
if(state.getBlock() == Blocks.BEDROCK || state.getBlock() != Blocks.END_STONE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidDimension(DimensionType dimension) {
|
||||
return dimension == DimensionType.THE_END;
|
||||
}
|
||||
|
||||
public static List<Finder> create(World world, ChunkPos chunkPos) {
|
||||
List<Finder> finders = new ArrayList<>();
|
||||
finders.add(new EndGatewayFinder(world, chunkPos));
|
||||
return finders;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-3
@@ -1,7 +1,9 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.population;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.PillarData;
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
@@ -45,8 +47,11 @@ public class EndPillarsFinder extends Finder {
|
||||
|
||||
if(result.size() == this.bedrockMarkers.length) {
|
||||
PillarData pillarData = new PillarData(result.stream().map(Vec3i::getY).collect(Collectors.toList()));
|
||||
result.forEach(pos -> this.renderers.add(new Cube(pos, new Vector4f(0.5f, 0.0f, 0.5f, 1.0f))));
|
||||
SeedCracker.get().onPillarData(pillarData);
|
||||
|
||||
if(SeedCracker.get().onPillarData(pillarData)){
|
||||
result.forEach(pos -> this.renderers.add(new Cube(pos, new Vector4f(0.5f, 0.0f, 0.5f, 1.0f))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.population;
|
||||
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.util.PosIterator;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
+6
-21
@@ -1,6 +1,6 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.population.ore;
|
||||
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -10,14 +10,13 @@ import net.minecraft.world.gen.feature.OreFeatureConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class DiamondOreFinder extends OreFinder {
|
||||
public class DiamondOreFinder extends SimpleOreFinder {
|
||||
|
||||
public static OreFeatureConfig CONFIG = new OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE, Blocks.DIAMOND_ORE.getDefaultState(), 8);
|
||||
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = buildSearchPositions(CHUNK_POSITIONS, pos -> {
|
||||
if(pos.getY() > 16)return true;
|
||||
if(pos.getY() > 16 + 4)return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -27,22 +26,8 @@ public class DiamondOreFinder extends OreFinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findOreVeins(List<Set<BlockPos>> veins) {
|
||||
List<BlockPos> starts = new ArrayList<>();
|
||||
|
||||
for(Set<BlockPos> vein: veins) {
|
||||
BlockPos oreStart = new BlockPos(
|
||||
this.findX(vein, OreFinder.HIGHEST),
|
||||
this.findY(vein, OreFinder.LOWEST) + 3,
|
||||
this.findZ(vein, OreFinder.HIGHEST)
|
||||
);
|
||||
|
||||
starts.add(oreStart);
|
||||
}
|
||||
|
||||
starts.forEach(start -> {
|
||||
this.renderers.add(new Cube(start, new Vector4f(1.0f, 1.0f, 1.0f, 1.0f)));
|
||||
});
|
||||
public Vector4f getRenderColor() {
|
||||
return new Vector4f(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
public static List<Finder> create(World world, ChunkPos chunkPos) {
|
||||
@@ -0,0 +1,57 @@
|
||||
package kaptainwutax.seedcracker.finder.population.ore;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.DecoratorCache;
|
||||
import kaptainwutax.seedcracker.cracker.EmeraldOreData;
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class EmeraldOreFinder extends BlockFinder {
|
||||
|
||||
public EmeraldOreFinder(World world, ChunkPos chunkPos) {
|
||||
super(world, chunkPos, Blocks.EMERALD_ORE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> findInChunk() {
|
||||
Biome biome = this.world.getBiome(this.chunkPos.getCenterBlockPos().add(8, 0, 8));
|
||||
|
||||
if(DecoratorCache.get().getSalt(biome, Decorator.EMERALD_ORE, false) == DecoratorCache.INVALID) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<BlockPos> result = super.findInChunk();
|
||||
|
||||
if(SeedCracker.get().onPopulationData(new EmeraldOreData(this.chunkPos, biome, result))) {
|
||||
result.forEach(pos -> {
|
||||
this.renderers.add(new Cube(pos, new Vector4f(0.0f, 1.0f, 0.0f, 1.0f)));
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidDimension(DimensionType dimension) {
|
||||
return dimension == DimensionType.OVERWORLD;
|
||||
}
|
||||
|
||||
public static List<Finder> create(World world, ChunkPos chunkPos) {
|
||||
List<Finder> finders = new ArrayList<>();
|
||||
finders.add(new EmeraldOreFinder(world, chunkPos));
|
||||
return finders;
|
||||
}
|
||||
|
||||
}
|
||||
+7
-24
@@ -1,6 +1,6 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.population.ore;
|
||||
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
@@ -10,14 +10,13 @@ import net.minecraft.world.gen.feature.OreFeatureConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class InfestedStoneOreFinder extends OreFinder {
|
||||
public class InfestedStoneOreFinder extends SimpleOreFinder {
|
||||
|
||||
public static OreFeatureConfig CONFIG = new OreFeatureConfig(OreFeatureConfig.Target.NATURAL_STONE, Blocks.INFESTED_STONE.getDefaultState(), 9);
|
||||
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = buildSearchPositions(CHUNK_POSITIONS, pos -> {
|
||||
if(pos.getY() > 70)return true;
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = Finder.buildSearchPositions(Finder.CHUNK_POSITIONS, pos -> {
|
||||
if(pos.getY() > 64 + 4)return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
@@ -27,24 +26,8 @@ public class InfestedStoneOreFinder extends OreFinder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findOreVeins(List<Set<BlockPos>> veins) {
|
||||
List<BlockPos> starts = new ArrayList<>();
|
||||
|
||||
for(Set<BlockPos> vein: veins) {
|
||||
if(vein.size() != 8)continue;
|
||||
|
||||
BlockPos oreStart = new BlockPos(
|
||||
this.findX(vein, OreFinder.HIGHEST),
|
||||
this.findY(vein, OreFinder.LOWEST) + 3,
|
||||
this.findZ(vein, OreFinder.HIGHEST)
|
||||
);
|
||||
|
||||
starts.add(oreStart);
|
||||
}
|
||||
|
||||
starts.forEach(start -> {
|
||||
this.renderers.add(new Cube(start, new Vector4f(0.0f, 1.0f, 1.0f, 1.0f)));
|
||||
});
|
||||
public Vector4f getRenderColor() {
|
||||
return new Vector4f(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
public static List<Finder> create(World world, ChunkPos chunkPos) {
|
||||
@@ -0,0 +1,50 @@
|
||||
package kaptainwutax.seedcracker.finder.population.ore;
|
||||
|
||||
import kaptainwutax.seedcracker.finder.population.OreFinder;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.gen.feature.OreFeatureConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class SimpleOreFinder extends OreFinder {
|
||||
|
||||
public SimpleOreFinder(World world, ChunkPos chunkPos, OreFeatureConfig oreFeatureConfig) {
|
||||
super(world, chunkPos, oreFeatureConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findOreVeins(List<Set<BlockPos>> veins) {
|
||||
List<BlockPos> starts = new ArrayList<>();
|
||||
|
||||
for(Set<BlockPos> vein: veins) {
|
||||
//This is a semi-accurate estimate.
|
||||
BlockPos oreStart = new BlockPos(
|
||||
this.findX(vein, OreFinder.HIGHEST),
|
||||
this.findY(vein, OreFinder.LOWEST) + 2,
|
||||
this.findZ(vein, OreFinder.HIGHEST)
|
||||
);
|
||||
|
||||
starts.add(oreStart);
|
||||
}
|
||||
|
||||
//If the start overlaps with another chunk, get rid of it.
|
||||
starts.removeIf(start -> {
|
||||
if((start.getX() & 15) == 0 || (start.getX() & 15) == 15)return true;
|
||||
if((start.getZ() & 15) == 0 || (start.getZ() & 15) == 15)return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
starts.forEach(start -> {
|
||||
this.renderers.add(new Cuboid(start.add(-1, -1, -1), start.add(1, 0, 1), this.getRenderColor()));
|
||||
});
|
||||
}
|
||||
|
||||
public abstract Vector4f getRenderColor();
|
||||
|
||||
}
|
||||
+12
-1
@@ -1,11 +1,14 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -40,9 +43,17 @@ public abstract class AbstractTempleFinder extends Finder {
|
||||
}
|
||||
|
||||
public List<BlockPos> findInChunkPiece(PieceFinder pieceFinder) {
|
||||
Biome biome = this.world.getBiome(this.chunkPos.getCenterBlockPos().add(9, 0, 9));
|
||||
|
||||
if(!biome.hasStructureFeature(this.getStructureFeature())) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
return pieceFinder.findInChunk();
|
||||
}
|
||||
|
||||
protected abstract StructureFeature<?> getStructureFeature();
|
||||
|
||||
public Map<PieceFinder, List<BlockPos>> findInChunkPieces() {
|
||||
Map<PieceFinder, List<BlockPos>> result = new HashMap<>();
|
||||
|
||||
+6
-1
@@ -1,7 +1,9 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.BlockFinder;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
@@ -41,6 +43,9 @@ public class BuriedTreasureFinder extends BlockFinder {
|
||||
CHEST_HOLDERS.add(Blocks.COAL_ORE.getDefaultState());
|
||||
CHEST_HOLDERS.add(Blocks.IRON_ORE.getDefaultState());
|
||||
CHEST_HOLDERS.add(Blocks.GOLD_ORE.getDefaultState());
|
||||
|
||||
//Ocean can turn stone into gravel.
|
||||
CHEST_HOLDERS.add(Blocks.GRAVEL.getDefaultState());
|
||||
}
|
||||
|
||||
public BuriedTreasureFinder(World world, ChunkPos chunkPos) {
|
||||
+8
-9
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
@@ -12,8 +13,8 @@ import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -31,13 +32,6 @@ public class DesertTempleFinder extends AbstractTempleFinder {
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
positions.removeIf(pos -> {
|
||||
Biome biome = world.getBiome(pos.add(9, 0, 9));
|
||||
if(!biome.hasStructureFeature(Feature.DESERT_PYRAMID))return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
@@ -50,6 +44,11 @@ public class DesertTempleFinder extends AbstractTempleFinder {
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StructureFeature<?> getStructureFeature() {
|
||||
return Feature.DESERT_PYRAMID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildStructure(PieceFinder finder) {
|
||||
BlockState blockState_1 = Blocks.SANDSTONE_STAIRS.getDefaultState().with(StairsBlock.FACING, Direction.NORTH);
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
+31
-46
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
@@ -9,39 +10,52 @@ import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class IglooFinder extends Finder {
|
||||
public class IglooFinder extends AbstractTempleFinder {
|
||||
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = buildSearchPositions(CHUNK_POSITIONS, pos -> {
|
||||
return false;
|
||||
});
|
||||
|
||||
protected List<PieceFinder> finders = new ArrayList<>();
|
||||
protected final Vec3i size = new Vec3i(7, 5, 8);
|
||||
|
||||
public IglooFinder(World world, ChunkPos chunkPos) {
|
||||
super(world, chunkPos);
|
||||
|
||||
Direction.Type.HORIZONTAL.forEach(direction -> {
|
||||
PieceFinder finder = new PieceFinder(world, chunkPos, direction, size);
|
||||
super(world, chunkPos, new Vec3i(7, 5, 8));
|
||||
|
||||
//Igloos are weird.
|
||||
this.finders.forEach(finder -> {
|
||||
finder.searchPositions = SEARCH_POSITIONS;
|
||||
|
||||
buildStructure(finder);
|
||||
this.finders.add(finder);
|
||||
});
|
||||
}
|
||||
|
||||
private void buildStructure(PieceFinder finder) {
|
||||
@Override
|
||||
public List<BlockPos> findInChunk() {
|
||||
Map<PieceFinder, List<BlockPos>> result = this.findInChunkPieces();
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
if(SeedCracker.get().onStructureData(new StructureData(this.chunkPos, StructureData.IGLOO))) {
|
||||
this.renderers.add(new Cuboid(pos, pieceFinder.getLayout(), new Vector4f(0.0f, 1.0f, 1.0f, 1.0f)));
|
||||
this.renderers.add(new Cube(pos, new Vector4f(0.0f, 1.0f, 1.0f, 1.0f)));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildStructure(PieceFinder finder) {
|
||||
BlockState air = Blocks.AIR.getDefaultState();
|
||||
BlockState snow = Blocks.SNOW_BLOCK.getDefaultState();
|
||||
BlockState ice = Blocks.ICE.getDefaultState();
|
||||
@@ -72,37 +86,8 @@ public class IglooFinder extends Finder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> findInChunk() {
|
||||
Map<PieceFinder, List<BlockPos>> result = this.findInChunkPieces();
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
positions.removeIf(pos -> {
|
||||
//Figure this out, it's not a trivial task.
|
||||
return false;
|
||||
});
|
||||
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
if(SeedCracker.get().onStructureData(new StructureData(this.chunkPos, StructureData.IGLOO))) {
|
||||
this.renderers.add(new Cuboid(pos, pieceFinder.getLayout(), new Vector4f(0.0f, 1.0f, 1.0f, 1.0f)));
|
||||
this.renderers.add(new Cube(pos, new Vector4f(0.0f, 1.0f, 1.0f, 1.0f)));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
public Map<PieceFinder, List<BlockPos>> findInChunkPieces() {
|
||||
Map<PieceFinder, List<BlockPos>> result = new HashMap<>();
|
||||
|
||||
this.finders.forEach(pieceFinder -> {
|
||||
result.put(pieceFinder, pieceFinder.findInChunk());
|
||||
});
|
||||
|
||||
return result;
|
||||
protected StructureFeature<?> getStructureFeature() {
|
||||
return Feature.IGLOO;
|
||||
}
|
||||
|
||||
@Override
|
||||
+8
-9
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.*;
|
||||
import net.minecraft.block.enums.WallMountLocation;
|
||||
@@ -12,8 +13,8 @@ import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -31,13 +32,6 @@ public class JungleTempleFinder extends AbstractTempleFinder {
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
positions.removeIf(pos -> {
|
||||
Biome biome = world.getBiome(pos.add(9, 0, 9));
|
||||
if(!biome.hasStructureFeature(Feature.JUNGLE_TEMPLE))return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
@@ -50,6 +44,11 @@ public class JungleTempleFinder extends AbstractTempleFinder {
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StructureFeature<?> getStructureFeature() {
|
||||
return Feature.JUNGLE_TEMPLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildStructure(PieceFinder finder) {
|
||||
BlockState eastStairs = Blocks.COBBLESTONE_STAIRS.getDefaultState().with(StairsBlock.FACING, Direction.EAST);
|
||||
@@ -0,0 +1,103 @@
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.util.math.Vector4f;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class MansionFinder extends Finder {
|
||||
|
||||
protected static List<BlockPos> SEARCH_POSITIONS = buildSearchPositions(CHUNK_POSITIONS, pos -> {
|
||||
if(pos.getY() != 64)return true;
|
||||
if((pos.getX() & 15) != 0)return true;
|
||||
if((pos.getZ() & 15) != 0)return true;
|
||||
return false;
|
||||
});
|
||||
|
||||
protected List<PieceFinder> finders = new ArrayList<>();
|
||||
protected Vec3i size = new Vec3i(16, 8, 16);
|
||||
|
||||
public MansionFinder(World world, ChunkPos chunkPos) {
|
||||
super(world, chunkPos);
|
||||
|
||||
Direction.Type.HORIZONTAL.forEach(direction -> {
|
||||
PieceFinder finder = new PieceFinder(world, chunkPos, direction, size);
|
||||
|
||||
finder.searchPositions = SEARCH_POSITIONS;
|
||||
|
||||
buildStructure(finder);
|
||||
this.finders.add(finder);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlockPos> findInChunk() {
|
||||
Map<PieceFinder, List<BlockPos>> result = this.findInChunkPieces();
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
positions.removeIf(pos -> {
|
||||
//Figure this out, it's not a trivial task.
|
||||
return false;
|
||||
});
|
||||
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
if(SeedCracker.get().onStructureData(new StructureData(this.chunkPos, StructureData.WOODLAND_MANSION))) {
|
||||
this.renderers.add(new Cuboid(pos, pieceFinder.getLayout(), new Vector4f(0.4f, 0.26f, 0.13f, 1.0f)));
|
||||
this.renderers.add(new Cube(this.chunkPos.getCenterBlockPos().add(0, pos.getY(), 0), new Vector4f(0.4f, 0.26f, 0.13f, 1.0f)));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
public Map<PieceFinder, List<BlockPos>> findInChunkPieces() {
|
||||
Map<PieceFinder, List<BlockPos>> result = new HashMap<>();
|
||||
|
||||
this.finders.forEach(pieceFinder -> {
|
||||
result.put(pieceFinder, pieceFinder.findInChunk());
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void buildStructure(PieceFinder finder) {
|
||||
BlockState cobblestone = Blocks.COBBLESTONE.getDefaultState();
|
||||
BlockState birchPlanks = Blocks.BIRCH_PLANKS.getDefaultState();
|
||||
BlockState redCarpet = Blocks.RED_CARPET.getDefaultState();
|
||||
BlockState whiteCarpet = Blocks.WHITE_CARPET.getDefaultState();
|
||||
|
||||
//TODO: Finish this.
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidDimension(DimensionType dimension) {
|
||||
return dimension == DimensionType.OVERWORLD;
|
||||
}
|
||||
|
||||
public static List<Finder> create(World world, ChunkPos chunkPos) {
|
||||
List<Finder> finders = new ArrayList<>();
|
||||
finders.add(new MansionFinder(world, chunkPos));
|
||||
return finders;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cube;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
+26
-15
@@ -1,22 +1,23 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.BlockMirror;
|
||||
import net.minecraft.util.BlockRotation;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PieceFinder extends Finder {
|
||||
|
||||
protected Map<BlockPos, BlockState> structure = new HashMap<>();
|
||||
protected Map<BlockPos, BlockState> structure = new LinkedHashMap<>();
|
||||
private MutableIntBoundingBox boundingBox;
|
||||
protected List<BlockPos> searchPositions = new ArrayList<>();
|
||||
|
||||
@@ -28,6 +29,8 @@ public class PieceFinder extends Finder {
|
||||
protected int height;
|
||||
protected int depth;
|
||||
|
||||
private boolean debug;
|
||||
|
||||
public PieceFinder(World world, ChunkPos chunkPos, Direction facing, Vec3i size) {
|
||||
super(world, chunkPos);
|
||||
|
||||
@@ -61,19 +64,22 @@ public class PieceFinder extends Finder {
|
||||
public List<BlockPos> findInChunk() {
|
||||
List<BlockPos> result = new ArrayList<>();
|
||||
|
||||
Chunk chunk = this.world.getChunk(this.chunkPos.getCenterBlockPos());
|
||||
if(this.structure.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//FOR DEBUGGING PIECES.
|
||||
if(this.debug) {
|
||||
MinecraftClient.getInstance().execute(() -> {
|
||||
int y = this.rotation.ordinal() * 10 + this.mirror.ordinal() * 20 + 100;
|
||||
|
||||
/*//FOR DEBUGGING PIECES.
|
||||
MinecraftClient.getInstance().execute(() -> {
|
||||
int y = this.rotation.ordinal() * 10 + this.mirror.ordinal() * 20 + 80;
|
||||
|
||||
if(this.chunkPos.x % 2 == 0 && this.chunkPos.z % 2 == 0) {
|
||||
this.structure.forEach((pos, state) -> {
|
||||
this.world.setBlockState(this.chunkPos.getCenterBlockPos().add(pos).add(0, y, 0), state);
|
||||
});
|
||||
}
|
||||
});*/
|
||||
if (this.chunkPos.x % 2 == 0 && this.chunkPos.z % 2 == 0) {
|
||||
this.structure.forEach((pos, state) -> {
|
||||
this.world.setBlockState(this.chunkPos.getCenterBlockPos().add(pos).add(0, y, 0), state, 0);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for(BlockPos center: this.searchPositions) {
|
||||
boolean found = true;
|
||||
@@ -221,4 +227,9 @@ public class PieceFinder extends Finder {
|
||||
public boolean isValidDimension(DimensionType dimension) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setDebug() {
|
||||
this.debug = true;
|
||||
}
|
||||
|
||||
}
|
||||
+8
-9
@@ -1,7 +1,8 @@
|
||||
package kaptainwutax.seedcracker.finder;
|
||||
package kaptainwutax.seedcracker.finder.structure;
|
||||
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import kaptainwutax.seedcracker.cracker.StructureData;
|
||||
import kaptainwutax.seedcracker.finder.Finder;
|
||||
import kaptainwutax.seedcracker.render.Cuboid;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
@@ -13,8 +14,8 @@ import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -32,13 +33,6 @@ public class SwampHutFinder extends AbstractTempleFinder {
|
||||
List<BlockPos> combinedResult = new ArrayList<>();
|
||||
|
||||
result.forEach((pieceFinder, positions) -> {
|
||||
positions.removeIf(pos -> {
|
||||
Biome biome = world.getBiome(pos.add(9, 0, 9));
|
||||
if(!biome.hasStructureFeature(Feature.SWAMP_HUT))return true;
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
combinedResult.addAll(positions);
|
||||
|
||||
positions.forEach(pos -> {
|
||||
@@ -51,6 +45,11 @@ public class SwampHutFinder extends AbstractTempleFinder {
|
||||
return combinedResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected StructureFeature<?> getStructureFeature() {
|
||||
return Feature.SWAMP_HUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildStructure(PieceFinder finder) {
|
||||
finder.fillWithOutline(1, 1, 1, 5, 1, 7, Blocks.SPRUCE_PLANKS.getDefaultState(), Blocks.SPRUCE_PLANKS.getDefaultState(), false);
|
||||
@@ -2,8 +2,8 @@ package kaptainwutax.seedcracker.mixin;
|
||||
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import kaptainwutax.seedcracker.ClientCommands;
|
||||
import kaptainwutax.seedcracker.FinderQueue;
|
||||
import kaptainwutax.seedcracker.command.ClientCommands;
|
||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package kaptainwutax.seedcracker.mixin;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import kaptainwutax.seedcracker.ClientCommands;
|
||||
import kaptainwutax.seedcracker.command.ClientCommands;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Mixin(ClientPlayerEntity.class)
|
||||
public class ClientPlayerEntityMixin {
|
||||
|
||||
@@ -17,10 +19,8 @@ public class ClientPlayerEntityMixin {
|
||||
|
||||
StringReader reader = new StringReader(message);
|
||||
reader.skip();
|
||||
int cursor = reader.getCursor();
|
||||
reader.setCursor(cursor);
|
||||
|
||||
if(ClientCommands.isClientSideCommand(message.substring(1).split(" "))) {
|
||||
if(ClientCommands.isClientSideCommand(message.substring(1).split(Pattern.quote(" ")))) {
|
||||
ClientCommands.executeCommand(reader);
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package kaptainwutax.seedcracker.mixin;
|
||||
|
||||
import kaptainwutax.seedcracker.FinderQueue;
|
||||
import kaptainwutax.seedcracker.finder.FinderQueue;
|
||||
import kaptainwutax.seedcracker.SeedCracker;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
@@ -8,6 +8,8 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
@Mixin(ClientWorld.class)
|
||||
public abstract class ClientWorldMixin {
|
||||
|
||||
@@ -15,6 +17,8 @@ public abstract class ClientWorldMixin {
|
||||
private void disconnect(CallbackInfo ci) {
|
||||
SeedCracker.get().clear();
|
||||
FinderQueue.get().clear();
|
||||
FinderQueue.SERVICE.shutdown();
|
||||
FinderQueue.SERVICE = Executors.newFixedThreadPool(5);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user