use of org.pepsoft.worldpainter.layers.Layer in project WorldPainter by Captain-Chaos.
the class AbstractWorldExporter method setupDimensionForExport.
@NotNull
private Map<Layer, LayerExporter> setupDimensionForExport(Dimension dimension) {
// Gather all layers used on the map
final Map<Layer, LayerExporter> exporters = new HashMap<>();
Set<Layer> allLayers = dimension.getAllLayers(false);
allLayers.addAll(dimension.getMinimumLayers());
// If there are combined layers, apply them and gather any newly
// added layers, recursively
boolean done;
do {
done = true;
for (Layer layer : new HashSet<>(allLayers)) {
if ((layer instanceof CombinedLayer) && ((CombinedLayer) layer).isExport()) {
// Apply the combined layer
Set<Layer> addedLayers = ((CombinedLayer) layer).apply(dimension);
// Remove the combined layer from the list
allLayers.remove(layer);
// Add any layers it might have added
allLayers.addAll(addedLayers);
// Signal that we have to go around at least once more,
// in case any of the newly added layers are themselves
// combined layers
done = false;
}
}
} while (!done);
// Remove layers which have been excluded for export
allLayers.removeIf(layer -> (layer instanceof CustomLayer) && (!((CustomLayer) layer).isExport()));
// Load all layer settings into the exporters
for (Layer layer : allLayers) {
@SuppressWarnings("unchecked") LayerExporter exporter = layer.getExporter();
if (exporter != null) {
exporter.setSettings(dimension.getLayerSettings(layer));
exporters.put(layer, exporter);
}
}
return exporters;
}
use of org.pepsoft.worldpainter.layers.Layer in project WorldPainter by Captain-Chaos.
the class AbstractWorldExporter method secondPass.
protected List<Fixup> secondPass(List<Layer> secondaryPassLayers, Dimension dimension, MinecraftWorld minecraftWorld, Map<Layer, LayerExporter> exporters, Collection<Tile> tiles, Point regionCoords, ProgressReceiver progressReceiver) throws OperationCancelled {
// Apply other secondary pass layers
if (logger.isDebugEnabled()) {
logger.debug("Start of second pass for region {},{}", regionCoords.x, regionCoords.y);
}
int layerCount = secondaryPassLayers.size(), counter = 0;
Rectangle area = new Rectangle((regionCoords.x << 9) - 16, (regionCoords.y << 9) - 16, 544, 544);
Rectangle exportedArea = new Rectangle((regionCoords.x << 9), (regionCoords.y << 9), 512, 512);
List<Fixup> fixups = new ArrayList<>();
// boolean frost = false;
for (Layer layer : secondaryPassLayers) {
// if (layer instanceof Frost) {
// frost = true;
// continue;
// }
@SuppressWarnings("unchecked") SecondPassLayerExporter exporter = (SecondPassLayerExporter) exporters.get(layer);
if (logger.isDebugEnabled()) {
logger.debug("Exporting layer {} for region {},{}", layer, regionCoords.x, regionCoords.y);
}
if (progressReceiver != null) {
if (minecraftWorld instanceof InvertedWorld) {
progressReceiver.setMessage("Exporting layer " + layer + " for ceiling");
} else {
progressReceiver.setMessage("Exporting layer " + layer);
}
}
List<Fixup> layerFixups = exporter.render(dimension, area, exportedArea, minecraftWorld);
if (layerFixups != null) {
fixups.addAll(layerFixups);
}
if (progressReceiver != null) {
counter++;
progressReceiver.setProgress((float) counter / layerCount);
}
}
// Garden / seeds first and second pass
GardenExporter gardenExporter = new GardenExporter();
Set<Seed> firstPassProcessedSeeds = new HashSet<>();
Set<Seed> secondPassProcessedSeeds = new HashSet<>();
tiles.stream().filter(tile -> tile.getLayers().contains(GardenCategory.INSTANCE)).forEach(tile -> {
gardenExporter.firstPass(dimension, tile, minecraftWorld, firstPassProcessedSeeds);
gardenExporter.secondPass(dimension, tile, minecraftWorld, secondPassProcessedSeeds);
});
// elegant
if ((dimension.getDim() == 0) && world.isCreateGoodiesChest()) {
Point goodiesPoint = (Point) world.getSpawnPoint().clone();
goodiesPoint.translate(3, 3);
int height = Math.min(dimension.getIntHeightAt(goodiesPoint) + 1, dimension.getMaxHeight() - 1);
minecraftWorld.setMaterialAt(goodiesPoint.x, goodiesPoint.y, height, Material.CHEST_NORTH);
Chunk chunk = minecraftWorld.getChunk(goodiesPoint.x >> 4, goodiesPoint.y >> 4);
if ((chunk != null) && (chunk.getTileEntities() != null)) {
Chest goodiesChest = createGoodiesChest();
goodiesChest.setX(goodiesPoint.x);
goodiesChest.setY(height);
goodiesChest.setZ(goodiesPoint.y);
chunk.getTileEntities().add(goodiesChest);
}
}
if (logger.isDebugEnabled()) {
logger.debug("End of second pass for region {},{}", regionCoords.x, regionCoords.y);
}
return fixups;
}
use of org.pepsoft.worldpainter.layers.Layer in project WorldPainter by Captain-Chaos.
the class Tile method containsOneOf.
public boolean containsOneOf(Layer... layers) {
boolean bitLayersAvailable = false, nonBitLayersAvailable = false;
for (Layer layer : layers) {
switch(layer.getDataSize()) {
case BIT:
case BIT_PER_CHUNK:
if (!bitLayersAvailable) {
ensureReadable(BIT_LAYER_DATA);
bitLayersAvailable = true;
}
if (bitLayerData.containsKey(layer)) {
return true;
}
break;
case BYTE:
case NIBBLE:
if (!nonBitLayersAvailable) {
ensureReadable(LAYER_DATA);
nonBitLayersAvailable = true;
}
if (layerData.containsKey(layer)) {
return true;
}
break;
default:
throw new IllegalArgumentException("Data size " + layer.getDataSize() + " not supported");
}
}
return false;
}
use of org.pepsoft.worldpainter.layers.Layer in project WorldPainter by Captain-Chaos.
the class Tile method getActiveLayers.
public List<Layer> getActiveLayers(int x, int y) {
ensureReadable(BIT_LAYER_DATA);
ensureReadable(LAYER_DATA);
List<Layer> activeLayers = new ArrayList<>(bitLayerData.size() + layerData.size());
for (Map.Entry<Layer, BitSet> entry : bitLayerData.entrySet()) {
final Layer layer = entry.getKey();
final DataSize dataSize = layer.getDataSize();
if (((dataSize == DataSize.BIT) && getBitPerBlockLayerValue(entry.getValue(), x, y)) || ((dataSize == DataSize.BIT_PER_CHUNK) && getBitPerChunkLayerValue(entry.getValue(), x, y))) {
activeLayers.add(layer);
}
}
for (Map.Entry<Layer, byte[]> entry : layerData.entrySet()) {
final Layer layer = entry.getKey();
final DataSize dataSize = layer.getDataSize();
final int defaultValue = layer.getDefaultValue();
if (dataSize == DataSize.NIBBLE) {
final int byteOffset = x | (y << TILE_SIZE_BITS);
final byte _byte = entry.getValue()[byteOffset / 2];
if ((byteOffset % 2 == 0) ? ((_byte & 0x0F) != defaultValue) : (((_byte & 0xF0) >> 4) != defaultValue)) {
activeLayers.add(layer);
}
} else if ((entry.getValue()[x | (y << TILE_SIZE_BITS)] & 0xFF) != defaultValue) {
activeLayers.add(layer);
}
}
return activeLayers;
}
use of org.pepsoft.worldpainter.layers.Layer in project WorldPainter by Captain-Chaos.
the class World2 method readObject.
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
propertyChangeSupport = new PropertyChangeSupport(this);
// Legacy maps
if (wpVersion < 1) {
if (maxheight == 0) {
maxheight = 128;
}
if (generator == null) {
generator = Generator.DEFAULT;
if ((generatorName != null) && generatorName.equals("FLAT")) {
generator = Generator.FLAT;
} else {
TileFactory tileFactory = dimensions.containsKey(0) ? dimensions.get(0).getTileFactory() : null;
if (tileFactory instanceof HeightMapTileFactory) {
if (((HeightMapTileFactory) tileFactory).getWaterHeight() < 32) {
// Low level
generator = Generator.FLAT;
}
}
}
}
if (biomeAlgorithm == BIOME_ALGORITHM_CUSTOM_BIOMES) {
customBiomes = true;
}
if (upIs == null) {
upIs = Direction.WEST;
askToRotate = true;
}
if ((!allowMerging) && (biomeAlgorithm != BIOME_ALGORITHM_NONE)) {
customBiomes = false;
}
if (mixedMaterials == null) {
mixedMaterials = new MixedMaterial[Terrain.CUSTOM_TERRAIN_COUNT];
if (customMaterials != null) {
for (int i = 0; i < customMaterials.length; i++) {
if (customMaterials[i] != null) {
mixedMaterials[i] = MixedMaterial.create(customMaterials[i]);
}
}
customMaterials = null;
}
}
Dimension dim = dimensions.get(DIM_NORMAL);
if (dim != null) {
// Migrate to refactored automatic biomes
if (biomeAlgorithm == BIOME_ALGORITHM_AUTO_BIOMES) {
// Automatic biomes was enabled; biome information should
// be present throughout; no need to do anything. Schedule a
// warning to warn the user about the change though
warnings = EnumSet.of(Warning.AUTO_BIOMES_DISABLED);
} else if (customBiomes) {
// Custom biomes was enabled; a mix of initialised and
// uninitialised tiles may be present which would be
// problematic, as the initialised tiles would have been
// initialised to zero and the default is now 255. Check what
// the situation is and take appropriate steps
boolean tilesWithBiomesFound = false, tilesWithoutBiomesFound = false;
for (Tile tile : dim.getTiles()) {
if (tile.hasLayer(Biome.INSTANCE)) {
tilesWithBiomesFound = true;
} else {
tilesWithoutBiomesFound = true;
}
}
if (tilesWithBiomesFound) {
if (tilesWithoutBiomesFound) {
// behaviour
for (Tile tile : dim.getTiles()) {
if (!tile.hasLayer(Biome.INSTANCE)) {
for (int x = 0; x < TILE_SIZE; x++) {
for (int y = 0; y < TILE_SIZE; y++) {
tile.setLayerValue(Biome.INSTANCE, x, y, 0);
}
}
}
}
} else {
// There are only initialised tiles. Good, we can leave
// it like that, and don't have to warn the user, as the
// behaviour will not change
}
} else if (tilesWithoutBiomesFound) {
// There are only uninitialised tiles. Leave it like that,
// but warn the user that automatic biomes is now active
warnings = EnumSet.of(Warning.AUTO_BIOMES_ENABLED);
}
} else {
// Neither custom nor automatic biomes was enabled; all
// tiles *should* be uninitialised, but clear the layer data
// anyway just to make sure. Schedule a warning to warn the user
// that automatic biomes are now active
dim.clearLayerData(Biome.INSTANCE);
warnings = EnumSet.of(Warning.AUTO_BIOMES_ENABLED);
}
}
}
if (wpVersion < 2) {
if (gameType == 3) {
difficulty = org.pepsoft.minecraft.Constants.DIFFICULTY_HARD;
} else {
difficulty = org.pepsoft.minecraft.Constants.DIFFICULTY_NORMAL;
}
}
if (wpVersion < 3) {
history = new ArrayList<>();
history.add(new HistoryEntry(HistoryEntry.WORLD_LEGACY_PRE_2_0_0));
}
if (wpVersion < 4) {
borderSettings = new BorderSettings();
}
if (wpVersion < 5) {
if (tilesToExport != null) {
dimensionsToExport = Collections.singleton(dimensionToExport);
} else {
dimensionsToExport = null;
}
dimensionToExport = -1;
}
if (wpVersion < 6) {
switch(version) {
case org.pepsoft.minecraft.Constants.SUPPORTED_VERSION_1:
platform = DefaultPlugin.JAVA_MCREGION;
break;
case org.pepsoft.minecraft.Constants.SUPPORTED_VERSION_2:
platform = DefaultPlugin.JAVA_ANVIL;
break;
default:
platform = (maxheight == org.pepsoft.minecraft.Constants.DEFAULT_MAX_HEIGHT_2) ? DefaultPlugin.JAVA_ANVIL : DefaultPlugin.JAVA_MCREGION;
}
version = -1;
gameTypeObj = GameType.values()[gameType];
gameType = -1;
}
wpVersion = CURRENT_WP_VERSION;
// Bug fix: fix the maxHeight of the dimensions, which somehow is not
// always correctly set (possibly only on imported worlds from
// non-standard height maps due to a bug which should be fixed).
dimensions.values().stream().filter(dimension -> dimension.getMaxHeight() != maxheight).forEach(dimension -> {
logger.warn("Fixing maxHeight of dimension " + dimension.getDim() + " (was " + dimension.getMaxHeight() + ", should be " + maxheight + ")");
dimension.setMaxHeight(maxheight);
dimension.setDirty(false);
});
// worlds for it
if (mixedMaterials.length != Terrain.CUSTOM_TERRAIN_COUNT) {
mixedMaterials = Arrays.copyOf(mixedMaterials, Terrain.CUSTOM_TERRAIN_COUNT);
}
}
Aggregations