use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class JavaWorldMerger method performSanityChecks.
/**
* Perform sanity checks to ensure the merge can proceed. Throws an
* {@link IllegalArgumentException} if the check fails, with the message
* describing the problem. Returns the loaded Minecraft level object as a
* convenience.
*
* @param biomesOnly Whether to check sanity for a biomes only merge (when
* <code>true</code>) or a full merge (when
* <code>false</code>).
* @return The loaded Minecraft level object, for convenience.
* @throws IllegalArgumentException If there is a problem that would prevent
* the merge from completing.
* @throws IOException If the level.dat file could not be read due to an I/O
* error.
*/
public Level performSanityChecks(boolean biomesOnly) throws IOException {
// Read existing level.dat file
Level level = Level.load(levelDatFile);
// Sanity checks
if (biomesOnly) {
int version = level.getVersion();
if (version == SUPPORTED_VERSION_1) {
throw new IllegalArgumentException("MCRegion (Minecraft 1.1) maps do not support biomes");
} else if (version != SUPPORTED_VERSION_2) {
throw new IllegalArgumentException("Version of existing map not supported: 0x" + Integer.toHexString(version));
}
} else {
int existingMaxHeight = level.getMaxHeight();
if (existingMaxHeight != world.getMaxHeight()) {
throw new IllegalArgumentException("Existing map has different max height (" + existingMaxHeight + ") than WorldPainter world (" + world.getMaxHeight() + ")");
}
int version = level.getVersion();
if ((version != SUPPORTED_VERSION_1) && (version != SUPPORTED_VERSION_2)) {
throw new IllegalArgumentException("Version of existing map not supported: 0x" + Integer.toHexString(version));
}
// Dimension sanity checks
for (Dimension dimension : world.getDimensions()) {
if (existingMaxHeight != dimension.getMaxHeight()) {
throw new IllegalArgumentException("Dimension " + dimension.getName() + " has different max height (" + dimension.getMaxHeight() + ") than existing map (" + existingMaxHeight + ")");
}
}
}
return level;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class JavaMapImporter method doImport.
public World2 doImport(ProgressReceiver progressReceiver) throws IOException, ProgressReceiver.OperationCancelled {
long start = System.currentTimeMillis();
logger.info("Importing map from " + levelDatFile.getAbsolutePath());
Level level = Level.load(levelDatFile);
int version = level.getVersion();
if ((version != SUPPORTED_VERSION_1) && (version != SUPPORTED_VERSION_2)) {
throw new UnsupportedOperationException("Level format version " + version + " not supported");
}
String name = level.getName().trim();
int maxHeight = level.getMaxHeight();
World2 world = new World2((version == SUPPORTED_VERSION_1) ? JAVA_MCREGION : JAVA_ANVIL, maxHeight);
world.addHistoryEntry(HistoryEntry.WORLD_IMPORTED_FROM_MINECRAFT_MAP, level.getName(), levelDatFile.getParentFile());
world.setCreateGoodiesChest(false);
world.setName(name);
world.setSpawnPoint(new Point(level.getSpawnX(), level.getSpawnZ()));
world.setImportedFrom(levelDatFile);
world.setMapFeatures(level.isMapFeatures());
if (level.isHardcore()) {
world.setGameType(GameType.HARDCORE);
} else {
world.setGameType(GameType.values()[level.getGameType()]);
}
world.setGenerator(level.getGenerator());
world.setGeneratorOptions(level.getGeneratorOptions());
world.setDifficulty(level.getDifficulty());
if ((version == SUPPORTED_VERSION_2) && (level.getBorderSize() > 0.0)) {
// If the world is version 0x4abd and actually has border settings,
// load them
world.getBorderSettings().setCentreX((int) (level.getBorderCenterX() + 0.5));
world.getBorderSettings().setCentreY((int) (level.getBorderCenterZ() + 0.5));
world.getBorderSettings().setSize((int) (level.getBorderSize() + 0.5));
world.getBorderSettings().setSafeZone((int) (level.getBorderSafeZone() + 0.5));
world.getBorderSettings().setWarningBlocks((int) (level.getBorderWarningBlocks() + 0.5));
world.getBorderSettings().setWarningTime((int) (level.getBorderWarningTime() + 0.5));
world.getBorderSettings().setSizeLerpTarget((int) (level.getBorderSizeLerpTarget() + 0.5));
world.getBorderSettings().setSizeLerpTime((int) level.getBorderSizeLerpTime());
world.getBorderSettings().setDamagePerBlock((int) (level.getBorderDamagePerBlock() + 0.5));
}
File worldDir = levelDatFile.getParentFile();
File regionDir = new File(worldDir, "region");
File netherDir = new File(worldDir, "DIM-1/region");
File endDir = new File(worldDir, "DIM1/region");
int dimCount = 1;
if (netherDir.isDirectory() && dimensionsToImport.contains(DIM_NETHER)) {
dimCount++;
}
if (endDir.isDirectory() && dimensionsToImport.contains(DIM_END)) {
dimCount++;
}
long minecraftSeed = level.getSeed();
tileFactory.setSeed(minecraftSeed);
Dimension dimension = new Dimension(minecraftSeed, tileFactory, DIM_NORMAL, maxHeight);
dimension.setEventsInhibited(true);
try {
dimension.setCoverSteepTerrain(false);
dimension.setSubsurfaceMaterial(Terrain.STONE);
dimension.setBorderLevel(62);
// Turn off smooth snow
FrostSettings frostSettings = new FrostSettings();
frostSettings.setMode(FrostSettings.MODE_FLAT);
dimension.setLayerSettings(Frost.INSTANCE, frostSettings);
ResourcesExporterSettings resourcesSettings = (ResourcesExporterSettings) dimension.getLayerSettings(Resources.INSTANCE);
resourcesSettings.setMinimumLevel(0);
if (version == SUPPORTED_VERSION_1) {
resourcesSettings.setChance(BLK_EMERALD_ORE, 0);
}
Configuration config = Configuration.getInstance();
dimension.setGridEnabled(config.isDefaultGridEnabled());
dimension.setGridSize(config.getDefaultGridSize());
dimension.setContoursEnabled(config.isDefaultContoursEnabled());
dimension.setContourSeparation(config.getDefaultContourSeparation());
String dimWarnings = importDimension(regionDir, dimension, version, (progressReceiver != null) ? new SubProgressReceiver(progressReceiver, 0.0f, 1.0f / dimCount) : null);
if (dimWarnings != null) {
if (warnings == null) {
warnings = dimWarnings;
} else {
warnings = warnings + dimWarnings;
}
}
} finally {
dimension.setEventsInhibited(false);
}
world.addDimension(dimension);
int dimNo = 1;
if (netherDir.isDirectory() && dimensionsToImport.contains(DIM_NETHER)) {
HeightMapTileFactory netherTileFactory = TileFactoryFactory.createNoiseTileFactory(minecraftSeed + 1, Terrain.NETHERRACK, maxHeight, 188, 192, true, false, 20f, 1.0);
SimpleTheme theme = (SimpleTheme) netherTileFactory.getTheme();
SortedMap<Integer, Terrain> terrainRanges = theme.getTerrainRanges();
terrainRanges.clear();
terrainRanges.put(-1, Terrain.NETHERRACK);
theme.setTerrainRanges(terrainRanges);
theme.setLayerMap(null);
dimension = new Dimension(minecraftSeed + 1, netherTileFactory, DIM_NETHER, maxHeight);
dimension.setEventsInhibited(true);
try {
dimension.setCoverSteepTerrain(false);
dimension.setSubsurfaceMaterial(Terrain.NETHERRACK);
ResourcesExporterSettings resourcesSettings = (ResourcesExporterSettings) dimension.getLayerSettings(Resources.INSTANCE);
resourcesSettings.setMinimumLevel(0);
if (version == SUPPORTED_VERSION_1) {
resourcesSettings.setChance(BLK_QUARTZ_ORE, 0);
}
String dimWarnings = importDimension(netherDir, dimension, version, (progressReceiver != null) ? new SubProgressReceiver(progressReceiver, (float) dimNo++ / dimCount, 1.0f / dimCount) : null);
if (dimWarnings != null) {
if (warnings == null) {
warnings = dimWarnings;
} else {
warnings = warnings + dimWarnings;
}
}
} finally {
dimension.setEventsInhibited(false);
}
world.addDimension(dimension);
}
if (endDir.isDirectory() && dimensionsToImport.contains(DIM_END)) {
HeightMapTileFactory endTileFactory = TileFactoryFactory.createNoiseTileFactory(minecraftSeed + 2, Terrain.END_STONE, maxHeight, 32, 0, false, false, 20f, 1.0);
SimpleTheme theme = (SimpleTheme) endTileFactory.getTheme();
SortedMap<Integer, Terrain> terrainRanges = theme.getTerrainRanges();
terrainRanges.clear();
terrainRanges.put(-1, Terrain.END_STONE);
theme.setTerrainRanges(terrainRanges);
theme.setLayerMap(Collections.emptyMap());
dimension = new Dimension(minecraftSeed + 2, endTileFactory, DIM_END, maxHeight);
dimension.setEventsInhibited(true);
try {
dimension.setCoverSteepTerrain(false);
dimension.setSubsurfaceMaterial(Terrain.END_STONE);
String dimWarnings = importDimension(endDir, dimension, version, (progressReceiver != null) ? new SubProgressReceiver(progressReceiver, (float) dimNo / dimCount, 1.0f / dimCount) : null);
if (dimWarnings != null) {
if (warnings == null) {
warnings = dimWarnings;
} else {
warnings = warnings + dimWarnings;
}
}
} finally {
dimension.setEventsInhibited(false);
}
world.addDimension(dimension);
}
// Log an event
Configuration config = Configuration.getInstance();
if (config != null) {
EventVO event = new EventVO(EVENT_KEY_ACTION_IMPORT_MAP).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(JAVA_ANVIL) && (world.getGenerator() == Generator.FLAT)) {
event.setAttribute(ATTRIBUTE_KEY_GENERATOR_OPTIONS, world.getGeneratorOptions());
}
event.setAttribute(ATTRIBUTE_KEY_TILES, dimension.getTiles().size());
config.logEvent(event);
}
return world;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class HeightMapImporter method importToNewWorld.
/**
* Create a new WorldPainter world from the configured height map and import
* settings.
*
* @param progressReceiver The progress receiver to report progress to and
* check for cancellation with.
* @return A new WorldPainter world based on the specified height map.
* @throws org.pepsoft.util.ProgressReceiver.OperationCancelled If and when
* the specified progress received throws it (when the user cancels the
* operation).
*/
public World2 importToNewWorld(ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled {
Rectangle extent = heightMap.getExtent();
logger.info("Importing world from height map {} (size: {}x{})", name, extent.width, extent.height);
final boolean highRes = (imageHighLevel >= maxHeight) && (worldHighLevel < maxHeight);
final World2 world = new World2((maxHeight == DEFAULT_MAX_HEIGHT_2) ? JAVA_ANVIL : JAVA_MCREGION, World2.DEFAULT_OCEAN_SEED, tileFactory, maxHeight);
world.addHistoryEntry(HistoryEntry.WORLD_IMPORTED_FROM_HEIGHT_MAP, imageFile);
int p = name.lastIndexOf('.');
if (p != -1) {
name = name.substring(0, p);
}
world.setName(name);
final Dimension dimension = world.getDimension(0);
// Export settings
final Configuration config = Configuration.getInstance();
final boolean minecraft11Only = dimension.getMaxHeight() != DEFAULT_MAX_HEIGHT_2;
world.setCreateGoodiesChest(config.isDefaultCreateGoodiesChest());
Generator generator = config.getDefaultGenerator();
if (minecraft11Only && (generator == Generator.LARGE_BIOMES)) {
generator = Generator.DEFAULT;
} else if ((!minecraft11Only) && (generator == Generator.DEFAULT)) {
generator = Generator.LARGE_BIOMES;
}
world.setGenerator(generator);
if (generator == Generator.FLAT) {
world.setGeneratorOptions(config.getDefaultGeneratorOptions());
}
world.setMapFeatures(config.isDefaultMapFeatures());
world.setGameType(config.getDefaultGameType());
world.setAllowCheats(config.isDefaultAllowCheats());
// Turn off smooth snow, except for high res imports
if (!highRes) {
FrostExporter.FrostSettings frostSettings = new FrostExporter.FrostSettings();
frostSettings.setMode(FrostExporter.FrostSettings.MODE_FLAT);
dimension.setLayerSettings(Frost.INSTANCE, frostSettings);
}
importToDimension(dimension, true, progressReceiver);
Dimension defaults = config.getDefaultTerrainAndLayerSettings();
dimension.setBorder(defaults.getBorder());
dimension.setBorderSize(defaults.getBorderSize());
dimension.setBorderLevel(worldWaterLevel);
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.setGridEnabled(config.isDefaultGridEnabled());
dimension.setGridSize(config.getDefaultGridSize());
dimension.setContoursEnabled(config.isDefaultContoursEnabled());
dimension.setContourSeparation(config.getDefaultContourSeparation());
world.setSpawnPoint(new Point(extent.x + extent.width / 2, extent.y + extent.height / 2));
dimension.setLastViewPosition(world.getSpawnPoint());
world.setDirty(false);
return world;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class LayerPreviewCreator method renderPreview.
public MinecraftWorldObject renderPreview() {
// Phase one: setup
long timestamp = System.currentTimeMillis();
long seed = 0L;
TileFactory tileFactory = subterranean ? TileFactoryFactory.createNoiseTileFactory(seed, Terrain.BARE_GRASS, previewHeight, 56, 62, false, true, 20f, 0.5) : TileFactoryFactory.createNoiseTileFactory(seed, Terrain.BARE_GRASS, previewHeight, 8, 14, false, true, 20f, 0.5);
Dimension dimension = new Dimension(seed, tileFactory, DIM_NORMAL, previewHeight);
dimension.setSubsurfaceMaterial(Terrain.STONE);
MinecraftWorldObject minecraftWorldObject = new MinecraftWorldObject(layer.getName() + " Preview", new Box(-8, 136, -8, 136, 0, previewHeight), previewHeight, null, new Point3i(-64, -64, 0));
long now = System.currentTimeMillis();
if (logger.isDebugEnabled()) {
logger.debug("Creating data structures took " + (now - timestamp) + " ms");
}
// Phase two: apply layer to dimension
timestamp = now;
Tile tile = tileFactory.createTile(0, 0);
switch(layer.getDataSize()) {
case BIT:
Random random = new Random(seed);
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
if (random.nextFloat() < pattern.getStrength(x, y)) {
tile.setBitLayerValue(layer, x, y, true);
}
}
}
break;
case BIT_PER_CHUNK:
random = new Random(seed);
for (int x = 0; x < 128; x += 16) {
for (int y = 0; y < 128; y += 16) {
if (random.nextFloat() < pattern.getStrength(x, y)) {
tile.setBitLayerValue(layer, x, y, true);
}
}
}
break;
case BYTE:
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
tile.setLayerValue(layer, x, y, Math.min((int) (pattern.getStrength(x, y) * 256), 255));
}
}
break;
case NIBBLE:
// any
if (layer instanceof CombinedLayer) {
final Terrain terrain = ((CombinedLayer) layer).getTerrain();
final int biome = ((CombinedLayer) layer).getBiome();
final boolean terrainConfigured = terrain != null;
final boolean biomeConfigured = biome != -1;
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
float strength = pattern.getStrength(x, y);
tile.setLayerValue(layer, x, y, Math.min((int) (strength * 16), 15));
// Double the strength so that 50% intensity results
// in full coverage for terrain and biome, which is
// inaccurate but probably more closely resembles
// practical usage
strength = Math.min(strength * 2, 1.0f);
if (terrainConfigured && ((strength > 0.95f) || (Math.random() < strength))) {
tile.setTerrain(x, y, terrain);
}
if (biomeConfigured && ((strength > 0.95f) || (Math.random() < strength))) {
tile.setLayerValue(Biome.INSTANCE, x, y, biome);
}
}
}
} else {
for (int x = 0; x < 128; x++) {
for (int y = 0; y < 128; y++) {
tile.setLayerValue(layer, x, y, Math.min((int) (pattern.getStrength(x, y) * 16), 15));
}
}
}
break;
default:
throw new IllegalArgumentException("Unsupported data size " + layer.getDataSize() + " encountered");
}
// If the layer is a combined layer, apply it recursively and collect
// the added layers
List<Layer> layers;
if (layer instanceof CombinedLayer) {
layers = new ArrayList<>();
layers.add(layer);
while (true) {
List<Layer> addedLayers = new ArrayList<>();
for (Iterator<Layer> i = layers.iterator(); i.hasNext(); ) {
Layer tmpLayer = i.next();
if (tmpLayer instanceof CombinedLayer) {
i.remove();
addedLayers.addAll(((CombinedLayer) tmpLayer).apply(tile));
}
}
if (!addedLayers.isEmpty()) {
layers.addAll(addedLayers);
} else {
break;
}
}
} else {
layers = Collections.singletonList(layer);
}
dimension.addTile(tile);
now = System.currentTimeMillis();
if (logger.isDebugEnabled()) {
logger.debug("Applying layer(s) took " + (now - timestamp) + " ms");
}
// Collect the exporters (could be multiple if the layer was a combined
// layer)
Map<Layer, LayerExporter> pass1Exporters = new HashMap<>();
Map<Layer, SecondPassLayerExporter> pass2Exporters = new HashMap<>();
for (Layer tmpLayer : layers) {
LayerExporter exporter = tmpLayer.getExporter();
if (tmpLayer.equals(layer)) {
exporter.setSettings(settings);
}
if (exporter instanceof FirstPassLayerExporter) {
pass1Exporters.put(layer, exporter);
}
if (exporter instanceof SecondPassLayerExporter) {
pass2Exporters.put(layer, (SecondPassLayerExporter) exporter);
}
}
// Phase three: generate terrain and render first pass layers, if any
timestamp = now;
WorldPainterChunkFactory chunkFactory = new WorldPainterChunkFactory(dimension, pass1Exporters, DefaultPlugin.JAVA_ANVIL, previewHeight);
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Chunk chunk = chunkFactory.createChunk(x, y).chunk;
minecraftWorldObject.addChunk(chunk);
}
}
now = System.currentTimeMillis();
if (logger.isDebugEnabled()) {
logger.debug("Generating terrain and rendering first pass layer(s) (if any) took " + (now - timestamp) + " ms");
}
if (!pass2Exporters.isEmpty()) {
// Phase four: render the second pass layers, if any
timestamp = now;
Rectangle area = new Rectangle(128, 128);
for (SecondPassLayerExporter exporter : pass2Exporters.values()) {
exporter.render(dimension, area, area, minecraftWorldObject);
}
now = System.currentTimeMillis();
if (logger.isDebugEnabled()) {
logger.debug("Rendering second pass layer(s) took " + (now - timestamp) + " ms");
}
}
// Final phase: post processing
timestamp = now;
now = System.currentTimeMillis();
try {
new JavaPostProcessor().postProcess(minecraftWorldObject, new Rectangle(-8, -8, 136, 136), null);
} catch (ProgressReceiver.OperationCancelled e) {
// Can't happen since we didn't pass in a progress receiver
throw new InternalError();
}
if (logger.isDebugEnabled()) {
logger.debug("Post processing took " + (now - timestamp) + " ms");
}
return minecraftWorldObject;
}
use of org.pepsoft.worldpainter.Dimension in project WorldPainter by Captain-Chaos.
the class InfoPanel method updateInfo.
void updateInfo() {
setTextIfDifferent(labelCoords, worldCoords.x + "," + worldCoords.y);
Dimension dim = view.getDimension();
if (dim == null) {
clearFields();
return;
}
Tile tile = dim.getTile(worldCoords.x >> TILE_SIZE_BITS, worldCoords.y >> TILE_SIZE_BITS);
if (tile == null) {
clearFields();
return;
}
final int x = worldCoords.x & TILE_SIZE_MASK, y = worldCoords.y & TILE_SIZE_MASK;
if (tile.getBitLayerValue(NotPresent.INSTANCE, x, y)) {
clearFields();
return;
}
fieldsClear = false;
float height = tile.getHeight(x, y);
setTextIfDifferent(labelHeight, heightFormatter.format(height));
int intHeight = (int) (height + 0.5f);
int waterLevel = tile.getWaterLevel(x, y);
setTextIfDifferent(labelWaterLevel, Integer.toString(waterLevel));
if (waterLevel > intHeight) {
setTextIfDifferent(labelWaterDepth, Integer.toString(waterLevel - intHeight));
} else {
setTextIfDifferent(labelWaterDepth, null);
}
float slope;
if ((x > 0) && (x < TILE_SIZE - 1) && (y > 0) && (y < TILE_SIZE - 1)) {
slope = tile.getSlope(x, y);
} else {
slope = dim.getSlope(worldCoords.x, worldCoords.y);
}
setTextIfDifferent(labelSlope, ((int) (Math.atan(slope) * 180 / Math.PI + 0.5)) + "°");
Terrain terrain = tile.getTerrain(x, y);
if (terrain != currentTerrain) {
labelTerrain.setText(terrain.getName());
labelTerrain.setIcon(new ImageIcon(terrain.getIcon(view.getColourScheme())));
currentTerrain = terrain;
}
int biome = tile.getLayerValue(Biome.INSTANCE, x, y);
boolean automaticBiome = false;
if (biome == 255) {
automaticBiome = true;
biome = dim.getAutoBiome(tile, x, y);
}
if (biome < 0) {
biome = Minecraft1_7Biomes.BIOME_PLAINS;
}
if ((automaticBiome != currentAutomaticBiome) || (biome != currentBiome)) {
labelBiome.setText(biomeHelper.getBiomeName(biome) + " (" + biome + ")");
labelBiome.setIcon(biomeHelper.getBiomeIcon(biome));
checkBoxAutomaticBiome.setSelected(automaticBiome);
currentAutomaticBiome = automaticBiome;
currentBiome = biome;
}
Map<Layer, Integer> layerValues = tile.getLayersAt(x, y);
if (layerValues != null) {
checkBoxInSelection.setSelected(layerValues.containsKey(SelectionChunk.INSTANCE) || layerValues.containsKey(SelectionBlock.INSTANCE));
layerValues.keySet().removeAll(HIDDEN_LAYERS);
if (!layerValues.isEmpty()) {
tableModel.update(layerValues);
} else {
tableModel.clear();
}
} else {
checkBoxInSelection.setSelected(false);
tableModel.clear();
}
}
Aggregations