use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class JavaWorldExporter method export.
@Override
public Map<Integer, ChunkFactory.Stats> export(File baseDir, String name, File backupDir, ProgressReceiver progressReceiver) throws IOException, ProgressReceiver.OperationCancelled {
// Sanity checks
if ((selectedTiles == null) && (selectedDimensions != null)) {
throw new IllegalArgumentException("Exporting a subset of dimensions not supported");
}
// Backup existing level
File worldDir = new File(baseDir, FileUtils.sanitiseName(name));
logger.info("Exporting world " + world.getName() + " to map at " + worldDir);
if (worldDir.isDirectory()) {
if (backupDir != null) {
logger.info("Directory already exists; backing up to " + backupDir);
if (!worldDir.renameTo(backupDir)) {
throw new FileInUseException("Could not move " + worldDir + " to " + backupDir);
}
} else {
throw new IllegalStateException("Directory already exists and no backup directory specified");
}
}
// Record start of export
long start = System.currentTimeMillis();
// Export dimensions
Dimension dim0 = world.getDimension(0);
Level level = new Level(world.getMaxHeight(), world.getPlatform());
level.setSeed(dim0.getMinecraftSeed());
level.setName(name);
Point spawnPoint = world.getSpawnPoint();
level.setSpawnX(spawnPoint.x);
level.setSpawnY(Math.max(dim0.getIntHeightAt(spawnPoint), dim0.getWaterLevelAt(spawnPoint)));
level.setSpawnZ(spawnPoint.y);
if (world.getGameType() == GameType.HARDCORE) {
level.setGameType(GAME_TYPE_SURVIVAL);
level.setHardcore(true);
level.setDifficulty(DIFFICULTY_HARD);
level.setDifficultyLocked(true);
level.setAllowCommands(false);
} else {
level.setGameType(world.getGameType().ordinal());
level.setHardcore(false);
level.setDifficulty(world.getDifficulty());
level.setAllowCommands(world.isAllowCheats());
}
Dimension.Border dim0Border = dim0.getBorder();
boolean endlessBorder = (dim0Border != null) && dim0Border.isEndless();
if (endlessBorder) {
StringBuilder generatorOptions = new StringBuilder("3;");
switch(dim0Border) {
case ENDLESS_LAVA:
case ENDLESS_WATER:
boolean bottomless = dim0.isBottomless();
int borderLevel = dim0.getBorderLevel();
int oceanDepth = Math.min(borderLevel / 2, 20);
int dirtDepth = borderLevel - oceanDepth - (bottomless ? 1 : 0);
if (!bottomless) {
generatorOptions.append("1*minecraft:bedrock,");
}
generatorOptions.append(dirtDepth);
generatorOptions.append("*minecraft:dirt,");
generatorOptions.append(oceanDepth);
generatorOptions.append((dim0Border == Dimension.Border.ENDLESS_WATER) ? "*minecraft:water;0;" : "*minecraft:lava;1;");
break;
case ENDLESS_VOID:
generatorOptions.append("1*minecraft:air;1;");
break;
}
generatorOptions.append(DEFAULT_GENERATOR_OPTIONS);
level.setMapFeatures(false);
level.setGenerator(Generator.FLAT);
level.setGeneratorOptions(generatorOptions.toString());
} else {
level.setMapFeatures(world.isMapFeatures());
level.setGenerator(world.getGenerator());
}
if (world.getPlatform().equals(DefaultPlugin.JAVA_ANVIL)) {
if ((!endlessBorder) && (world.getGenerator() == Generator.FLAT) && (world.getGeneratorOptions() != null)) {
level.setGeneratorOptions(world.getGeneratorOptions());
}
World2.BorderSettings borderSettings = world.getBorderSettings();
level.setBorderCenterX(borderSettings.getCentreX());
level.setBorderCenterZ(borderSettings.getCentreY());
level.setBorderSize(borderSettings.getSize());
level.setBorderSafeZone(borderSettings.getSafeZone());
level.setBorderWarningBlocks(borderSettings.getWarningBlocks());
level.setBorderWarningTime(borderSettings.getWarningTime());
level.setBorderSizeLerpTarget(borderSettings.getSizeLerpTarget());
level.setBorderSizeLerpTime(borderSettings.getSizeLerpTime());
level.setBorderDamagePerBlock(borderSettings.getDamagePerBlock());
}
// Save the level.dat file. This will also create a session.lock file, hopefully kicking out any Minecraft
// instances which may have the map open:
level.save(worldDir);
Map<Integer, ChunkFactory.Stats> stats = new HashMap<>();
int selectedDimension;
if (selectedTiles == null) {
selectedDimension = -1;
boolean first = true;
for (Dimension dimension : world.getDimensions()) {
if (dimension.getDim() < 0) {
// dimension, so skip it
continue;
}
if (first) {
first = false;
} else if (progressReceiver != null) {
progressReceiver.reset();
}
stats.put(dimension.getDim(), exportDimension(worldDir, dimension, world.getPlatform(), progressReceiver));
}
} else {
selectedDimension = selectedDimensions.iterator().next();
stats.put(selectedDimension, exportDimension(worldDir, world.getDimension(selectedDimension), world.getPlatform(), progressReceiver));
}
// Update the session.lock file, hopefully kicking out any Minecraft instances which may have tried to open the
// map in the mean time:
File sessionLockFile = new File(worldDir, "session.lock");
try (DataOutputStream sessionOut = new DataOutputStream(new FileOutputStream(sessionLockFile))) {
sessionOut.writeLong(System.currentTimeMillis());
}
// Record the export in the world history
if (selectedTiles == null) {
world.addHistoryEntry(HistoryEntry.WORLD_EXPORTED_FULL, name, worldDir);
} else {
world.addHistoryEntry(HistoryEntry.WORLD_EXPORTED_PARTIAL, name, worldDir, world.getDimension(selectedDimension).getName());
}
// Log an event
Configuration config = Configuration.getInstance();
if (config != null) {
EventVO event = new EventVO(EVENT_KEY_ACTION_EXPORT_WORLD).duration(System.currentTimeMillis() - start);
event.setAttribute(EventVO.ATTRIBUTE_TIMESTAMP, new Date(start));
event.setAttribute(ATTRIBUTE_KEY_MAX_HEIGHT, world.getMaxHeight());
event.setAttribute(ATTRIBUTE_KEY_PLATFORM, world.getPlatform().displayName);
event.setAttribute(ATTRIBUTE_KEY_MAP_FEATURES, world.isMapFeatures());
event.setAttribute(ATTRIBUTE_KEY_GAME_TYPE_NAME, world.getGameType().name());
event.setAttribute(ATTRIBUTE_KEY_ALLOW_CHEATS, world.isAllowCheats());
event.setAttribute(ATTRIBUTE_KEY_GENERATOR, world.getGenerator().name());
if (world.getPlatform().equals(DefaultPlugin.JAVA_ANVIL) && (world.getGenerator() == Generator.FLAT)) {
event.setAttribute(ATTRIBUTE_KEY_GENERATOR_OPTIONS, world.getGeneratorOptions());
}
Dimension dimension = world.getDimension(0);
event.setAttribute(ATTRIBUTE_KEY_TILES, dimension.getTiles().size());
logLayers(dimension, event, "");
dimension = world.getDimension(1);
if (dimension != null) {
event.setAttribute(ATTRIBUTE_KEY_NETHER_TILES, dimension.getTiles().size());
logLayers(dimension, event, "nether.");
}
dimension = world.getDimension(2);
if (dimension != null) {
event.setAttribute(ATTRIBUTE_KEY_END_TILES, dimension.getTiles().size());
logLayers(dimension, event, "end.");
}
if (selectedDimension != -1) {
event.setAttribute(ATTRIBUTE_KEY_EXPORTED_DIMENSION, selectedDimension);
event.setAttribute(ATTRIBUTE_KEY_EXPORTED_DIMENSION_TILES, selectedTiles.size());
}
if (world.getImportedFrom() != null) {
event.setAttribute(ATTRIBUTE_KEY_IMPORTED_WORLD, true);
}
config.logEvent(event);
}
return stats;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class JavaWorldExporter method exportDimension.
private ChunkFactory.Stats exportDimension(File worldDir, Dimension dimension, Platform platform, ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled, IOException {
File dimensionDir;
Dimension ceiling;
switch(dimension.getDim()) {
case DIM_NORMAL:
dimensionDir = worldDir;
ceiling = dimension.getWorld().getDimension(DIM_NORMAL_CEILING);
break;
case DIM_NETHER:
dimensionDir = new File(worldDir, "DIM-1");
ceiling = dimension.getWorld().getDimension(DIM_NETHER_CEILING);
break;
case DIM_END:
dimensionDir = new File(worldDir, "DIM1");
ceiling = dimension.getWorld().getDimension(DIM_END_CEILING);
break;
default:
throw new IllegalArgumentException("Dimension " + dimension.getDim() + " not supported");
}
File regionDir = new File(dimensionDir, "region");
if (!regionDir.exists()) {
if (!regionDir.mkdirs()) {
throw new RuntimeException("Could not create directory " + regionDir);
}
}
ChunkFactory.Stats collectedStats = parallelExportRegions(dimension, platform, worldDir, progressReceiver);
// Calculate total size of dimension
Set<Point> regions = new HashSet<>(), exportedRegions = new HashSet<>();
if (selectedTiles != null) {
for (Point tile : selectedTiles) {
regions.add(new Point(tile.x >> 2, tile.y >> 2));
}
} else {
for (Tile tile : dimension.getTiles()) {
// Also add regions for any bedrock wall and/or border
// tiles, if present
int r = (((dimension.getBorder() != null) && (!dimension.getBorder().isEndless())) ? dimension.getBorderSize() : 0) + (((dimension.getBorder() == null) || (!dimension.getBorder().isEndless())) && dimension.isBedrockWall() ? 1 : 0);
for (int dx = -r; dx <= r; dx++) {
for (int dy = -r; dy <= r; dy++) {
regions.add(new Point((tile.getX() + dx) >> 2, (tile.getY() + dy) >> 2));
}
}
}
if (ceiling != null) {
for (Tile tile : ceiling.getTiles()) {
regions.add(new Point(tile.getX() >> 2, tile.getY() >> 2));
}
}
}
for (Point region : regions) {
File file = new File(dimensionDir, "region/r." + region.x + "." + region.y + (platform.equals(DefaultPlugin.JAVA_ANVIL) ? ".mca" : ".mcr"));
collectedStats.size += file.length();
}
if (progressReceiver != null) {
progressReceiver.setProgress(1.0f);
}
return collectedStats;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class TestTool method main.
public static void main(String[] args) throws IOException, OperationCancelled {
Random random = new Random();
long seed = random.nextLong();
// TileFactory tileFactory = new NoiseTileFactory(Terrain.GRASS, DEFAULT_MAX_HEIGHT_2, 58, 62, false, false);
TileFactory tileFactory = TileFactoryFactory.createFlatTileFactory(seed, Terrain.GRASS, DEFAULT_MAX_HEIGHT_2, 62, 0, false, false);
World2 world = new World2(JAVA_ANVIL, seed, tileFactory, DEFAULT_MAX_HEIGHT_2);
world.setName("TestWorld");
world.setSpawnPoint(new Point(64, 64));
world.setGameType(GameType.CREATIVE);
Dimension dimension = world.getDimension(0);
dimension.addTile(tileFactory.createTile(0, 0));
Garden garden = dimension.getGarden();
// garden.plantSeed(inn);
while (!garden.tick()) ;
JavaWorldExporter worldExporter = new JavaWorldExporter(world);
File exportDir = new File(args[0]);
worldExporter.export(exportDir, "TestWorld", worldExporter.selectBackupDir(new File(exportDir, "TestWorld")), null);
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class RiverGenerator method generateRivers.
public void generateRivers() {
dimension.setEventsInhibited(true);
UndoManager undoManager = new UndoManager(2);
dimension.register(undoManager);
snapshot = dimension.getSnapshot();
dimension.armSavePoint();
garden = dimension.getGarden();
try {
dimension.getTiles().forEach(this::generateRivers);
// Grow seeds until all activity has ceased
while (!garden.tick()) ;
// Apply the river nodes to the landscape
// A river source
dimension.getGarden().getSeeds().stream().filter(seed -> (seed instanceof RiverNode) && (seed.getParent() == null)).forEach(seed -> {
// A river source
((RiverNode) seed).apply(dimension, snapshot, new HashSet<>());
});
} finally {
garden = null;
snapshot = null;
dimension.unregister();
dimension.setEventsInhibited(false);
}
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class PruneTiles method main.
public static void main(String[] args) throws IOException, ClassNotFoundException {
File worldFile = new File(args[0]);
int maxTileDistance = Integer.parseInt(args[1]);
World2 world;
try (ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(new FileInputStream(worldFile)))) {
world = (World2) in.readObject();
}
for (Dimension dimension : world.getDimensions()) {
for (Tile tile : dimension.getTiles()) {
int dx = Math.abs(tile.getX()), dy = Math.abs(tile.getY());
if ((dx > maxTileDistance) || (dy > maxTileDistance)) {
// It's an outlier. Remove it
System.out.println("Removing tile at " + tile.getX() + ", " + tile.getY());
dimension.removeTile(tile);
}
}
}
try (ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(worldFile)))) {
out.writeObject(world);
}
}
Aggregations