use of org.pepsoft.worldpainter.Platform in project WorldPainter by Captain-Chaos.
the class AbstractWorldExporter method firstPass.
protected ExportResults firstPass(MinecraftWorld minecraftWorld, Dimension dimension, Point regionCoords, Map<Point, Tile> tiles, boolean tileSelection, Map<Layer, LayerExporter> exporters, ChunkFactory chunkFactory, boolean ceiling, ProgressReceiver progressReceiver) throws OperationCancelled, IOException {
if (logger.isDebugEnabled()) {
logger.debug("Start of first pass for region {},{}", regionCoords.x, regionCoords.y);
}
if (progressReceiver != null) {
if (ceiling) {
progressReceiver.setMessage("Generating ceiling");
} else {
progressReceiver.setMessage("Generating landscape");
}
}
int lowestChunkX = (regionCoords.x << 5) - 1;
int highestChunkX = (regionCoords.x << 5) + 32;
int lowestChunkY = (regionCoords.y << 5) - 1;
int highestChunkY = (regionCoords.y << 5) + 32;
int lowestRegionChunkX = lowestChunkX + 1;
int highestRegionChunkX = highestChunkX - 1;
int lowestRegionChunkY = lowestChunkY + 1;
int highestRegionChunkY = highestChunkY - 1;
ExportResults exportResults = new ExportResults();
int chunkNo = 0;
int ceilingDelta = dimension.getMaxHeight() - dimension.getCeilingHeight();
Platform platform = world.getPlatform();
PlatformProvider platformProvider = PlatformManager.getInstance().getPlatformProvider(platform);
for (int chunkX = lowestChunkX; chunkX <= highestChunkX; chunkX++) {
for (int chunkY = lowestChunkY; chunkY <= highestChunkY; chunkY++) {
ChunkFactory.ChunkCreationResult chunkCreationResult = createChunk(dimension, chunkFactory, tiles, chunkX, chunkY, tileSelection, exporters, ceiling);
if (chunkCreationResult != null) {
if ((chunkX >= lowestRegionChunkX) && (chunkX <= highestRegionChunkX) && (chunkY >= lowestRegionChunkY) && (chunkY <= highestRegionChunkY)) {
exportResults.chunksGenerated = true;
exportResults.stats.landArea += chunkCreationResult.stats.landArea;
exportResults.stats.surfaceArea += chunkCreationResult.stats.surfaceArea;
exportResults.stats.waterArea += chunkCreationResult.stats.waterArea;
}
if (ceiling) {
Chunk invertedChunk = new InvertedChunk(chunkCreationResult.chunk, ceilingDelta);
Chunk existingChunk = minecraftWorld.getChunkForEditing(chunkX, chunkY);
if (existingChunk == null) {
existingChunk = platformProvider.createChunk(platform, chunkX, chunkY, world.getMaxHeight());
minecraftWorld.addChunk(existingChunk);
}
mergeChunks(invertedChunk, existingChunk);
} else {
minecraftWorld.addChunk(chunkCreationResult.chunk);
}
}
chunkNo++;
if (progressReceiver != null) {
progressReceiver.setProgress((float) chunkNo / 1156);
}
}
}
if (logger.isDebugEnabled()) {
logger.debug("End of first pass for region {},{}", regionCoords.x, regionCoords.y);
}
return exportResults;
}
use of org.pepsoft.worldpainter.Platform in project WorldPainter by Captain-Chaos.
the class BedrockWallChunk method create.
public static ChunkFactory.ChunkCreationResult create(int chunkX, int chunkZ, Dimension dimension) {
final int maxHeight = dimension.getMaxHeight();
final Platform platform = dimension.getWorld().getPlatform();
final ChunkFactory.ChunkCreationResult result = new ChunkFactory.ChunkCreationResult();
result.chunk = PlatformManager.getInstance().createChunk(platform, chunkX, chunkZ, maxHeight);
final int maxY = maxHeight - 1;
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
if (platform.capabilities.contains(BIOMES)) {
result.chunk.setBiome(x, z, BIOME_PLAINS);
}
for (int y = 0; y <= maxY; y++) {
result.chunk.setBlockType(x, y, z, BLK_BEDROCK);
}
result.chunk.setHeight(x, z, maxY);
}
}
result.chunk.setTerrainPopulated(true);
result.stats.landArea = 0;
result.stats.surfaceArea = 256;
result.stats.waterArea = 0;
return result;
}
use of org.pepsoft.worldpainter.Platform in project WorldPainter by Captain-Chaos.
the class BorderChunkFactory method create.
public static ChunkFactory.ChunkCreationResult create(int chunkX, int chunkZ, Dimension dimension, Map<Layer, LayerExporter> exporters) {
final int maxHeight = dimension.getMaxHeight();
final Platform platform = dimension.getWorld().getPlatform();
final Border border = dimension.getBorder();
final int borderLevel = dimension.getBorderLevel();
final boolean dark = dimension.isDarkLevel();
final boolean bottomless = dimension.isBottomless();
final Terrain subsurfaceMaterial = dimension.getSubsurfaceMaterial();
final PerlinNoise noiseGenerator;
if (noiseGenerators.get() == null) {
noiseGenerator = new PerlinNoise(0);
noiseGenerators.set(noiseGenerator);
} else {
noiseGenerator = noiseGenerators.get();
}
final long seed = dimension.getSeed();
if (noiseGenerator.getSeed() != seed) {
noiseGenerator.setSeed(seed);
}
final int floor = Math.max(borderLevel - 20, 0);
final int variation = Math.min(15, (borderLevel - floor) / 2);
final ChunkFactory.ChunkCreationResult result = new ChunkFactory.ChunkCreationResult();
result.chunk = PlatformManager.getInstance().createChunk(platform, chunkX, chunkZ, maxHeight);
final int maxY = maxHeight - 1;
if (platform.capabilities.contains(BIOMES)) {
switch(border) {
case VOID:
case LAVA:
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
result.chunk.setBiome(x, z, BIOME_PLAINS);
}
}
break;
case WATER:
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
result.chunk.setBiome(x, z, BIOME_OCEAN);
}
}
break;
default:
throw new InternalError();
}
}
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
if (border != Border.VOID) {
final int worldX = (chunkX << 4) | x, worldZ = (chunkZ << 4) | z;
final int floorLevel = (int) (floor + (noiseGenerator.getPerlinNoise(worldX / MEDIUM_BLOBS, worldZ / MEDIUM_BLOBS) + 0.5f) * variation + 0.5f);
final int surfaceLayerLevel = floorLevel - dimension.getTopLayerDepth(worldX, worldZ, floorLevel);
for (int y = 0; y <= maxY; y++) {
if ((y == 0) && (!bottomless)) {
result.chunk.setBlockType(x, y, z, BLK_BEDROCK);
} else if (y <= surfaceLayerLevel) {
result.chunk.setMaterial(x, y, z, subsurfaceMaterial.getMaterial(seed, worldX, worldZ, y, floorLevel));
} else if (y <= floorLevel) {
result.chunk.setMaterial(x, y, z, BEACHES.getMaterial(seed, worldX, worldZ, y, floorLevel));
} else if (y <= borderLevel) {
switch(border) {
case WATER:
result.chunk.setBlockType(x, y, z, BLK_STATIONARY_WATER);
break;
case LAVA:
result.chunk.setBlockType(x, y, z, BLK_STATIONARY_LAVA);
break;
default:
}
}
}
}
if (dark) {
result.chunk.setBlockType(x, maxY, z, BLK_BEDROCK);
result.chunk.setHeight(x, z, maxY);
} else if (border == Border.VOID) {
result.chunk.setHeight(x, z, 0);
} else {
result.chunk.setHeight(x, z, (borderLevel < maxY) ? (borderLevel + 1) : maxY);
}
}
}
if (border != Border.VOID) {
// Apply layers set to be applied everywhere, if any
final Set<Layer> minimumLayers = dimension.getMinimumLayers();
if (!minimumLayers.isEmpty()) {
Tile virtualTile = new Tile(chunkX >> 3, chunkZ >> 3, dimension.getMaxHeight()) {
@Override
public synchronized float getHeight(int x, int y) {
return floor + (noiseGenerator.getPerlinNoise(((getX() << TILE_SIZE_BITS) | x) / MEDIUM_BLOBS, ((getY() << TILE_SIZE_BITS) | y) / MEDIUM_BLOBS) + 0.5f) * variation;
}
@Override
public synchronized int getWaterLevel(int x, int y) {
return borderLevel;
}
private static final long serialVersionUID = 1L;
};
for (Layer layer : minimumLayers) {
LayerExporter layerExporter = exporters.get(layer);
if (layerExporter instanceof FirstPassLayerExporter) {
((FirstPassLayerExporter) layerExporter).render(dimension, virtualTile, result.chunk);
}
}
}
}
result.chunk.setTerrainPopulated(true);
result.stats.surfaceArea = 256;
if ((border == Border.WATER) || (border == Border.LAVA)) {
result.stats.waterArea = 256;
}
return result;
}
use of org.pepsoft.worldpainter.Platform in project WorldPainter by Captain-Chaos.
the class Mapper method map.
private static void map(final File worldDir, final int dim, final ColourScheme colourScheme, File output) throws IOException, InterruptedException {
File levelDatFile = new File(worldDir, "level.dat");
Level level = Level.load(levelDatFile);
final Platform platform = level.getVersion() == SUPPORTED_VERSION_1 ? DefaultPlugin.JAVA_MCREGION : DefaultPlugin.JAVA_ANVIL;
maxHeight = level.getMaxHeight();
File dimensionDir;
switch(dim) {
case 0:
dimensionDir = worldDir;
break;
case 1:
dimensionDir = new File(worldDir, "DIM-1");
break;
case 2:
dimensionDir = new File(worldDir, "DIM1");
break;
default:
throw new IllegalArgumentException(Integer.toString(dim));
}
final File regionDir = new File(dimensionDir, "region");
if (!regionDir.exists()) {
error("Map does not have dimension " + dim);
}
System.out.println("Mapping " + worldDir);
System.out.println("Name: " + level.getName());
System.out.println("Seed: " + level.getSeed());
if (level.getGeneratorName() != null) {
System.out.println("Generator: " + level.getGeneratorName() + " (version " + level.getGeneratorVersion() + ")");
}
System.out.println("Map height: " + maxHeight);
System.out.println("Storage format: " + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? "McRegion (Minecraft 1.1 or earlier)" : "Anvil (Minecraft 1.2 or later)"));
// Determine size
File[] regionFiles = regionDir.listFiles(platform.equals(DefaultPlugin.JAVA_MCREGION) ? (dir, name) -> name.toLowerCase().endsWith(".mcr") : (FilenameFilter) (dir, name) -> name.toLowerCase().endsWith(".mca"));
int tmpLowestRegionX = Integer.MAX_VALUE, tmpHighestRegionX = Integer.MIN_VALUE;
int tmpLowestRegionZ = Integer.MAX_VALUE, tmpHighestRegionZ = Integer.MIN_VALUE;
for (File regionFile : regionFiles) {
String[] parts = regionFile.getName().split("\\.");
int regionX = Integer.parseInt(parts[1]);
int regionZ = Integer.parseInt(parts[2]);
if (regionX < tmpLowestRegionX) {
tmpLowestRegionX = regionX;
}
if (regionX > tmpHighestRegionX) {
tmpHighestRegionX = regionX;
}
if (regionZ < tmpLowestRegionZ) {
tmpLowestRegionZ = regionZ;
}
if (regionZ > tmpHighestRegionZ) {
tmpHighestRegionZ = regionZ;
}
}
final int lowestRegionX = tmpLowestRegionX, highestRegionX = tmpHighestRegionX;
final int lowestRegionZ = tmpLowestRegionZ, highestRegionZ = tmpHighestRegionZ;
int tmpLowestChunkX = Integer.MAX_VALUE, tmpHighestChunkX = Integer.MIN_VALUE;
int tmpLowestChunkZ = Integer.MAX_VALUE, tmpHighestChunkZ = Integer.MIN_VALUE;
for (int regionX = lowestRegionX; regionX <= highestRegionX; regionX++) {
File file = new File(regionDir, "r." + regionX + "." + lowestRegionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = regionX << 5;
int regionChunkZ = lowestRegionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
file = new File(regionDir, "r." + regionX + "." + highestRegionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = regionX << 5;
int regionChunkZ = highestRegionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
}
for (int regionZ = lowestRegionZ + 1; regionZ <= highestRegionZ - 1; regionZ++) {
File file = new File(regionDir, "r." + lowestRegionX + "." + regionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = lowestRegionX << 5;
int regionChunkZ = regionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
file = new File(regionDir, "r." + highestRegionX + "." + regionZ + (platform.equals(DefaultPlugin.JAVA_MCREGION) ? ".mcr" : ".mca"));
if (file.exists()) {
int regionChunkX = highestRegionX << 5;
int regionChunkZ = regionZ << 5;
RegionFile region = new RegionFile(file);
try {
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkZ = 0; chunkZ < 32; chunkZ++) {
if (region.containsChunk(chunkX, chunkZ)) {
int x = regionChunkX + chunkX;
int z = regionChunkZ + chunkZ;
if (x < tmpLowestChunkX) {
tmpLowestChunkX = x;
}
if (x > tmpHighestChunkX) {
tmpHighestChunkX = x;
}
if (z < tmpLowestChunkZ) {
tmpLowestChunkZ = z;
}
if (z > tmpHighestChunkZ) {
tmpHighestChunkZ = z;
}
}
}
}
} finally {
region.close();
}
}
}
final int lowestChunkX = tmpLowestChunkX;
final int lowestChunkZ = tmpLowestChunkZ;
int widthChunks = (tmpHighestChunkX - tmpLowestChunkX + 1);
int heightChunks = (tmpHighestChunkZ - tmpLowestChunkZ + 1);
System.out.println("Width: " + (widthChunks << 4));
System.out.println("Height: " + (heightChunks << 4));
final BufferedImage image = new BufferedImage(widthChunks << 4, heightChunks << 4, BufferedImage.TYPE_INT_ARGB);
final int imageOffsetX = lowestChunkX << 4;
final int imageOffsetY = lowestChunkZ << 4;
final int waterColour = colourScheme.getColour(Material.WATER);
final int lavaColour = colourScheme.getColour(Material.LAVA);
final int snowColour = colourScheme.getColour(Material.SNOW);
int threads = Runtime.getRuntime().availableProcessors();
System.out.print("Mapping");
ExecutorService executorService = Executors.newFixedThreadPool(threads);
for (File file : regionFiles) {
final File finalFile = file;
executorService.submit(() -> {
try {
String[] parts = finalFile.getName().split("\\.");
int regionX = Integer.parseInt(parts[1]);
int regionY = Integer.parseInt(parts[2]);
WorldRegion world = new WorldRegion(worldDir, dim, regionX, regionY, maxHeight, platform);
int[][] heightCache = new int[544][544];
for (int i = 0; i < 544; i++) {
Arrays.fill(heightCache[i], -1);
}
for (int chunkX = 0; chunkX < 32; chunkX++) {
for (int chunkY = 0; chunkY < 32; chunkY++) {
int worldChunkX = (regionX << 5) | chunkX;
int worldChunkY = (regionY << 5) | chunkY;
if (world.isChunkPresent(worldChunkX, worldChunkY)) {
for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
int worldX = (worldChunkX << 4) | x;
int worldY = (worldChunkY << 4) | y;
boolean snow = false, water = false, lava = false;
int waterLevel = 0;
for (int height = maxHeight - 1; height >= 0; height--) {
int blockType = world.getBlockTypeAt(worldX, worldY, height);
if (blockType != BLK_AIR) {
if (blockType == BLK_SNOW) {
snow = true;
} else if ((blockType == BLK_STATIONARY_WATER) || (blockType == BLK_WATER) || (blockType == BLK_STATIONARY_LAVA) || (blockType == BLK_LAVA)) {
if ((world.getDataAt(worldX, worldY, height) == 0) && (waterLevel == 0)) {
waterLevel = height;
if ((blockType == BLK_LAVA) || (blockType == BLK_STATIONARY_LAVA)) {
lava = true;
} else {
water = true;
}
}
} else if (TERRAIN_BLOCKS.contains(blockType)) {
// Terrain found
int data = world.getDataAt(worldX, worldY, height);
int depth = waterLevel - height;
int fluidAlpha = 0xff >> Math.min(depth, 3);
int colour = colourScheme.getColour(blockType, data);
if (depth > 0) {
colour = ColourUtils.multiply(colour, getBrightenAmount(world, heightCache, ((chunkX + 1) << 4) | x, ((chunkY + 1) << 4) | y, regionX, regionY));
}
if (water) {
colour = ColourUtils.mix(colour, waterColour, fluidAlpha);
} else if (lava) {
colour = ColourUtils.mix(colour, lavaColour, fluidAlpha);
}
if (snow) {
colour = ColourUtils.mix(colour, snowColour, 64);
}
if (depth <= 0) {
colour = ColourUtils.multiply(colour, getBrightenAmount(world, heightCache, ((chunkX + 1) << 4) | x, ((chunkY + 1) << 4) | y, regionX, regionY));
}
image.setRGB(worldX - imageOffsetX, worldY - imageOffsetY, 0xff000000 | colour);
break;
} else {
// Non-terrain block found (not shaded)
int data = world.getDataAt(worldX, worldY, height);
int depth = waterLevel - height;
int fluidAlpha = 0xff >> Math.min(depth, 3);
int colour = colourScheme.getColour(blockType, data);
if (water) {
colour = ColourUtils.mix(colour, waterColour, fluidAlpha);
} else if (lava) {
colour = ColourUtils.mix(colour, lavaColour, fluidAlpha);
}
if (snow) {
colour = ColourUtils.mix(colour, snowColour);
}
image.setRGB(worldX - imageOffsetX, worldY - imageOffsetY, 0xff000000 | colour);
break;
}
}
}
}
}
}
}
}
System.out.print('.');
System.out.flush();
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
});
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.DAYS);
System.out.println();
// Save image
System.out.println("Saving image to " + output + "...");
ImageIO.write(image, "PNG", output);
System.out.println("Finished");
}
Aggregations