-
Notifications
You must be signed in to change notification settings - Fork 5
Open
Description
- There is a 1 in 10 chance that you will be misjudged when using this code to find an end city:
private static List<BlockPos> locateStructure(Seed seed, Feature feature, EndCityMode endCityMode, BlockPos center, int radius, int maxResults) {
Dimension dimension = getDimension(feature);
MCVersion mcVersion = seed.version;
Structure<?, ?> structure = getStructure(feature, mcVersion);
if (structure == null) return null;
BiomeSource biomeSource = BiomeSource.of(dimension, mcVersion, seed.seed);
if (!structure.isValidDimension(biomeSource.getDimension()))
return null;
List<BPos> structurePos = locateStructures(structure, new BPos(center.getX(), center.getY(), center.getZ()), endCityMode, radius, maxResults, new ChunkRand(), biomeSource, TerrainGenerator.of(biomeSource));
return toBlockPosList(structurePos);
}
private static List<BPos> locateStructures(Structure<?, ?> structure, BPos center, EndCityMode endCityMode, int radius, int maxResults, ChunkRand chunkRand, BiomeSource source, TerrainGenerator terrainGenerator) {
List<BPos> result = new ArrayList<>();
if (structure instanceof EndCity endCity) {
SpiralIterator<CPos> spiralIterator = new SpiralIterator<>(new CPos(center.getX() >> 4, center.getZ() >> 4), new CPos(radius, radius), (x, y, z) -> new CPos(x, z));
StreamSupport.stream(spiralIterator.spliterator(), false)
.filter(cPos -> {
com.seedfinding.mcfeature.Feature.Data<?> data = endCity.at(cPos.getX(), cPos.getZ());
EndCityGenerator endCityGenerator = new EndCityGenerator(source.getVersion());
return data.testStart(source.getWorldSeed(), chunkRand)
&& data.testBiome(source)
&& data.testGenerate(terrainGenerator)
&& switch (endCityMode) {
case OnlyHasShip -> endCityGenerator.generate(terrainGenerator, cPos) && endCityGenerator.hasShip();
case OnlyNotShip -> endCityGenerator.generate(terrainGenerator, cPos) && !endCityGenerator.hasShip();
case Both -> endCityGenerator.generate(terrainGenerator, cPos);
};
})
.limit(maxResults)
.forEach(cPos -> result.add(cPos.toBlockPos().add(9, 0, 9)));
} else if (structure instanceof RegionStructure<?, ?> regionStructure) {
int chunkInRegion = regionStructure.getSpacing();
int regionSize = chunkInRegion * 16;
final int border = 30_000_000;
SpiralIterator<RPos> spiralIterator = new SpiralIterator<>(center.toRegionPos(regionSize), new BPos(-border, 0, -border).toRegionPos(regionSize), new BPos(border, 0, border).toRegionPos(regionSize), 1, (x, y, z) -> new RPos(x, z, regionSize));
StreamSupport.stream(spiralIterator.spliterator(), false)
.map(rPos -> regionStructure.getInRegion(source.getWorldSeed(), rPos.getX(), rPos.getZ(), chunkRand))
.filter(Objects::nonNull)
.filter(cPos -> (regionStructure.canSpawn(cPos, source)) && (terrainGenerator == null || regionStructure.canGenerate(cPos, terrainGenerator)))
.limit(maxResults)
.forEach(cPos -> result.add(cPos.toBlockPos().add(9, 0, 9)));
} else {
if (structure instanceof Stronghold strongholdStructure) {
CPos currentChunkPos = center.toChunkPos();
int squaredDistance = Integer.MAX_VALUE;
for (CPos stronghold : strongholdStructure.getAllStarts(source, chunkRand)) {
if (result.size() >= maxResults) {
break;
}
int newSquaredDistance = (currentChunkPos.getX() - stronghold.getX()) * (currentChunkPos.getX() - stronghold.getX()) + (currentChunkPos.getZ() - stronghold.getZ()) * (currentChunkPos.getZ() - stronghold.getZ());
if (newSquaredDistance < squaredDistance) {
squaredDistance = newSquaredDistance;
result.clear();
result.add(stronghold.toBlockPos().add(9, 0, 9));
}
}
} else if (structure instanceof Mineshaft mineshaft) {
SpiralIterator<CPos> spiralIterator = new SpiralIterator<>(new CPos(center.getX() >> 4, center.getZ() >> 4), new CPos(radius, radius), (x, y, z) -> new CPos(x, z));
StreamSupport.stream(spiralIterator.spliterator(), false)
.filter(cPos -> {
com.seedfinding.mcfeature.Feature.Data<Mineshaft> data = mineshaft.at(cPos.getX(), cPos.getZ());
return data.testStart(source.getWorldSeed(), chunkRand) && data.testBiome(source) && data.testGenerate(terrainGenerator);
})
.limit(maxResults)
.forEach(cPos -> result.add(cPos.toBlockPos().add(9, 0, 9)));
}
}
return result;
}
private static Dimension getDimension(Feature feature) {
return switch (feature) {
case buried_treasure -> Dimension.OVERWORLD;
case mansion -> Dimension.OVERWORLD;
case stronghold -> Dimension.OVERWORLD;
case nether_fortress -> Dimension.NETHER;
case ocean_monument -> Dimension.OVERWORLD;
case bastion_remnant -> Dimension.NETHER;
case slime_chunk -> Dimension.OVERWORLD;
case village -> Dimension.OVERWORLD;
case mineshaft -> Dimension.OVERWORLD;
case end_city -> Dimension.END;
case desert_pyramid -> Dimension.OVERWORLD;
default -> Dimension.OVERWORLD;
};
}
private static boolean checkIfInDimension(Dimension dimension) {
return switch (dimension) {
case OVERWORLD -> (PlayerUtils.getDimension() == meteordevelopment.meteorclient.utils.world.Dimension.Overworld);
case NETHER -> (PlayerUtils.getDimension() == meteordevelopment.meteorclient.utils.world.Dimension.Nether);
case END -> (PlayerUtils.getDimension() == meteordevelopment.meteorclient.utils.world.Dimension.End);
};
}
private static Structure<?, ?> getStructure(Feature feature, MCVersion version) {
return switch (feature) {
case buried_treasure -> new BuriedTreasure(version);
case mansion -> new Mansion(version);
case stronghold -> new Stronghold(version);
case nether_fortress -> new Fortress(version);
case ocean_monument -> new Monument(version);
case bastion_remnant -> new BastionRemnant(version);
case end_city -> new EndCity(version);
case village -> new Village(version);
case mineshaft -> new Mineshaft(version);
case desert_pyramid -> new DesertPyramid(version);
default -> null;
};
}
private static List<BlockPos> toBlockPosList(List<BPos> posList) {
List<BlockPos> blockPosList = new ArrayList<>();
for (BPos pos : posList) {
blockPosList.add(new BlockPos(pos.getX(), pos.getY(), pos.getZ()));
}
return blockPosList;
}Seed: -3396536410594980164, Location: -3428 60-13070.
Judging from the seedMap, the location below 1.18.2 will refresh the end city, but above 1.18.2 is useless, I also tried to change the MCVersion of BiomeSource, but the result remains the same, so I suspect that it is an API problem.
Metadata
Metadata
Assignees
Labels
No labels