use of org.pepsoft.util.ProgressReceiver in project WorldPainter by Captain-Chaos.
the class NewWorldDialog method getSelectedDimension.
public Dimension getSelectedDimension(final ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled {
long minecraftSeed;
try {
minecraftSeed = Long.parseLong(fieldSeed.getText());
} catch (NumberFormatException e) {
minecraftSeed = fieldSeed.getText().hashCode();
}
if (radioButtonCustomSeed.isSelected()) {
worldpainterSeed = minecraftSeed;
}
int waterHeight = (Integer) spinnerWaterLevel.getValue();
final TileFactory tileFactory = createTileFactory(worldpainterSeed);
int maxHeight = (Integer) comboBoxMaxHeight.getSelectedItem();
final Dimension dimension = new Dimension(minecraftSeed, tileFactory, dim, maxHeight);
dimension.setEventsInhibited(true);
try {
ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
final AtomicBoolean cancelled = new AtomicBoolean();
if (tiles != null) {
logger.info("Creating new dimension with " + tiles.size() + " preselected tiles");
final int[] tileCount = new int[1];
final int totalTiles = tiles.size();
for (final Point tileCoords : tiles) {
executorService.execute(() -> {
if (cancelled.get()) {
// Operation cancelled by user
return;
}
Tile tile = tileFactory.createTile(tileCoords.x, tileCoords.y);
dimension.addTile(tile);
if (progressReceiver != null) {
synchronized (tileCount) {
tileCount[0]++;
try {
progressReceiver.setProgress((float) tileCount[0] / totalTiles);
} catch (ProgressReceiver.OperationCancelled e) {
cancelled.set(true);
}
}
}
});
}
} else if (checkBoxCircular.isSelected()) {
final int radius = (Integer) spinnerWidth.getValue() / 2;
int diameter = radius * 2;
logger.info("Creating new circular dimension with diameter " + diameter + " blocks");
int tileRadius = (radius + 127) / 128;
final int[] tileCount = new int[1];
final int approximateTotalTiles = (int) Math.ceil(Math.PI * tileRadius * tileRadius);
for (int x = -tileRadius; x < tileRadius; x++) {
for (int y = -tileRadius; y < tileRadius; y++) {
if (org.pepsoft.worldpainter.util.MathUtils.getSmallestDistanceFromOrigin(x, y) < radius) {
// At least one corner is inside the circle; include
// the tile. Note that this is always correct in
// this case only because the centre of the circle
// is always at a tile intersection so the circle
// can never "bulge" into a tile without any of the
// the tile's corners being inside the circle
final int tileX = x, tileY = y;
executorService.execute(() -> {
if (cancelled.get()) {
// Operation cancelled by user
return;
}
Tile tile = tileFactory.createTile(tileX, tileY);
dimension.addTile(tile);
if (org.pepsoft.worldpainter.util.MathUtils.getLargestDistanceFromOrigin(tileX, tileY) >= radius) {
// the edge
for (int xx = 0; xx < TILE_SIZE; xx++) {
for (int yy = 0; yy < TILE_SIZE; yy++) {
float distance = MathUtils.getDistance(tileX * TILE_SIZE + xx + 0.5f, tileY * TILE_SIZE + yy + 0.5f);
if (distance > radius) {
tile.setBitLayerValue(org.pepsoft.worldpainter.layers.Void.INSTANCE, xx, yy, true);
}
}
}
}
if (progressReceiver != null) {
synchronized (tileCount) {
tileCount[0]++;
try {
// System.out.println("Progress: " + tileCount[0] + " of " + approximateTotalTiles + " (" + ((float) tileCount[0] / approximateTotalTiles) + ")");
progressReceiver.setProgress(Math.min((float) tileCount[0] / approximateTotalTiles, 1.0f));
} catch (ProgressReceiver.OperationCancelled e) {
cancelled.set(true);
}
}
}
});
}
}
}
// Assume the user will want an endless void border by default;
// override the preferences
dimension.setBorder(Border.ENDLESS_VOID);
} else {
int width = ((Integer) spinnerWidth.getValue()) / 128;
int height = ((Integer) spinnerLength.getValue()) / 128;
logger.info("Creating new dimension of size " + width + "x" + height + " for a total of " + width * height + " tiles");
final int[] tileCount = new int[1];
final int totalTiles = width * height;
int startX = -width / 2;
int startY = -height / 2;
for (int x = startX; x < startX + width; x++) {
for (int y = startY; y < startY + height; y++) {
final int tileX = x, tileY = y;
executorService.execute(() -> {
if (cancelled.get()) {
// Operation cancelled by user
return;
}
Tile tile = tileFactory.createTile(tileX, tileY);
dimension.addTile(tile);
if (progressReceiver != null) {
synchronized (tileCount) {
tileCount[0]++;
try {
progressReceiver.setProgress((float) tileCount[0] / totalTiles);
} catch (ProgressReceiver.OperationCancelled e) {
cancelled.set(true);
}
}
}
});
}
}
}
// Wait for all tiles to be created
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
throw new RuntimeException("Thread interrupted", e);
}
if (cancelled.get()) {
// The operation was cancelled by the user
return null;
}
if (dim == DIM_NORMAL_CEILING) {
ResourcesExporter.ResourcesExporterSettings resourcesSettings = new ResourcesExporter.ResourcesExporterSettings(maxHeight);
// Invert min and max levels:
int maxZ = maxHeight - 1;
for (int blockType : resourcesSettings.getBlockTypes()) {
int low = resourcesSettings.getMinLevel(blockType);
int high = resourcesSettings.getMaxLevel(blockType);
resourcesSettings.setMinLevel(blockType, maxZ - high);
resourcesSettings.setMaxLevel(blockType, maxZ - low);
}
// Remove lava and water:
resourcesSettings.setChance(BLK_WATER, 0);
resourcesSettings.setChance(BLK_LAVA, 0);
dimension.setLayerSettings(Resources.INSTANCE, resourcesSettings);
} else if (dim == DIM_NETHER) {
dimension.setSubsurfaceMaterial(NETHERLIKE);
CavernsSettings cavernsSettings = new CavernsSettings();
cavernsSettings.setCavernsEverywhereLevel(16);
cavernsSettings.setSurfaceBreaking(true);
cavernsSettings.setFloodWithLava(true);
cavernsSettings.setWaterLevel(16);
dimension.setLayerSettings(Caverns.INSTANCE, cavernsSettings);
} else if (dim == DIM_NETHER_CEILING) {
dimension.setSubsurfaceMaterial(NETHERLIKE);
} else if ((dim == DIM_END) || (dim == DIM_END_CEILING)) {
dimension.setSubsurfaceMaterial(END_STONE);
}
Configuration config = Configuration.getInstance();
Dimension defaults = config.getDefaultTerrainAndLayerSettings();
if (dim == DIM_NORMAL) {
if (!checkBoxCircular.isSelected()) {
dimension.setBorder(defaults.getBorder());
dimension.setBorderSize(defaults.getBorderSize());
}
dimension.setBedrockWall(defaults.isBedrockWall());
dimension.setSubsurfaceMaterial(defaults.getSubsurfaceMaterial());
dimension.setPopulate(defaults.isPopulate());
dimension.setTopLayerMinDepth(defaults.getTopLayerMinDepth());
dimension.setTopLayerVariation(defaults.getTopLayerVariation());
dimension.setBottomless(defaults.isBottomless());
for (Map.Entry<Layer, ExporterSettings> entry : defaults.getAllLayerSettings().entrySet()) {
dimension.setLayerSettings(entry.getKey(), entry.getValue().clone());
}
}
dimension.setBorderLevel(waterHeight);
dimension.setCoverSteepTerrain(defaults.isCoverSteepTerrain());
dimension.setGridEnabled(config.isDefaultGridEnabled());
dimension.setGridSize(config.getDefaultGridSize());
dimension.setContoursEnabled(config.isDefaultContoursEnabled());
dimension.setContourSeparation(config.getDefaultContourSeparation());
} finally {
dimension.setEventsInhibited(false);
}
dimension.setDirty(false);
return dimension;
}
Aggregations