Search in sources :

Example 1 with CombinedLayer

use of org.pepsoft.worldpainter.layers.CombinedLayer in project WorldPainter by Captain-Chaos.

the class CombinedLayerPaint method apply.

@Override
public void apply(Dimension dimension, int centreX, int centreY, float dynamicLevel) {
    if (brush.getRadius() == 0) {
        // Special case: if the radius is 0, assume that the user wants to paint complete pixels instead of trying
        // to apply the brush
        applyPixel(dimension, centreX, centreY);
        return;
    }
    final int effectiveRadius = brush.getEffectiveRadius();
    final int x1 = centreX - effectiveRadius, y1 = centreY - effectiveRadius, x2 = centreX + effectiveRadius, y2 = centreY + effectiveRadius;
    final int tileX1 = x1 >> TILE_SIZE_BITS, tileY1 = y1 >> TILE_SIZE_BITS, tileX2 = x2 >> TILE_SIZE_BITS, tileY2 = y2 >> TILE_SIZE_BITS;
    final Terrain terrain = ((CombinedLayer) layer).getTerrain();
    final int biome = ((CombinedLayer) layer).getBiome();
    final boolean terrainConfigured = terrain != null;
    final boolean biomeConfigured = biome != -1;
    if ((tileX1 == tileX2) && (tileY1 == tileY2)) {
        // The bounding box of the brush is entirely on one tile; optimize by painting directly to the tile
        final Tile tile = dimension.getTileForEditing(tileX1, tileY1);
        if (tile == null) {
            return;
        }
        final int x1InTile = x1 & TILE_SIZE_MASK, y1InTile = y1 & TILE_SIZE_MASK, x2InTile = x2 & TILE_SIZE_MASK, y2InTile = y2 & TILE_SIZE_MASK;
        final int tileXInWorld = tileX1 << TILE_SIZE_BITS, tileYInWorld = tileY1 << TILE_SIZE_BITS;
        if (dither) {
            for (int y = y1InTile; y <= y2InTile; y++) {
                for (int x = x1InTile; x <= x2InTile; x++) {
                    final int currentValue = tile.getLayerValue(layer, x, y);
                    final float strength = dynamicLevel * getStrength(centreX, centreY, tileXInWorld + x, tileYInWorld + y);
                    if (strength != 0f) {
                        int targetValue = 1 + (int) (strength * 14 + 0.5f);
                        if (targetValue > currentValue) {
                            tile.setLayerValue(layer, x, y, targetValue);
                        }
                        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 y = y1InTile; y <= y2InTile; y++) {
                for (int x = x1InTile; x <= x2InTile; x++) {
                    final int currentValue = tile.getLayerValue(layer, x, y);
                    final float strength = dynamicLevel * getStrength(centreX, centreY, tileXInWorld + x, tileYInWorld + y);
                    if (strength != 0f) {
                        int targetValue = 1 + (int) (strength * 14 + 0.5f);
                        if (targetValue > currentValue) {
                            tile.setLayerValue(layer, x, y, targetValue);
                        }
                        if (dynamicLevel * getFullStrength(centreX, centreY, tileXInWorld + x, tileYInWorld + y) > 0.75f) {
                            if (terrainConfigured) {
                                tile.setTerrain(x, y, terrain);
                            }
                            if (biomeConfigured) {
                                tile.setLayerValue(Biome.INSTANCE, x, y, biome);
                            }
                        }
                    }
                }
            }
        }
    } else {
        // The bounding box of the brush straddles more than one tile; paint to the dimension
        if (dither) {
            for (int y = y1; y <= y2; y++) {
                for (int x = x1; x <= x2; x++) {
                    final int currentValue = dimension.getLayerValueAt(layer, x, y);
                    final float strength = dynamicLevel * getStrength(centreX, centreY, x, y);
                    if (strength != 0f) {
                        int targetValue = 1 + (int) (strength * 14 + 0.5f);
                        if (targetValue > currentValue) {
                            dimension.setLayerValueAt(layer, x, y, targetValue);
                        }
                        if (terrainConfigured && ((strength > 0.95f) || (Math.random() < strength))) {
                            dimension.setTerrainAt(x, y, terrain);
                        }
                        if (biomeConfigured && ((strength > 0.95f) || (Math.random() < strength))) {
                            dimension.setLayerValueAt(Biome.INSTANCE, x, y, biome);
                        }
                    }
                }
            }
        } else {
            for (int y = y1; y <= y2; y++) {
                for (int x = x1; x <= x2; x++) {
                    final int currentValue = dimension.getLayerValueAt(layer, x, y);
                    final float strength = dynamicLevel * getStrength(centreX, centreY, x, y);
                    if (strength != 0f) {
                        int targetValue = 1 + (int) (strength * 14 + 0.5f);
                        if (targetValue > currentValue) {
                            dimension.setLayerValueAt(layer, x, y, targetValue);
                        }
                        if (dynamicLevel * getFullStrength(centreX, centreY, x, y) > 0.75f) {
                            if (terrainConfigured) {
                                dimension.setTerrainAt(x, y, terrain);
                            }
                            if (biomeConfigured) {
                                dimension.setLayerValueAt(Biome.INSTANCE, x, y, biome);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : CombinedLayer(org.pepsoft.worldpainter.layers.CombinedLayer) Terrain(org.pepsoft.worldpainter.Terrain) Tile(org.pepsoft.worldpainter.Tile)

Example 2 with CombinedLayer

use of org.pepsoft.worldpainter.layers.CombinedLayer 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;
}
Also used : CustomLayer(org.pepsoft.worldpainter.layers.CustomLayer) CombinedLayer(org.pepsoft.worldpainter.layers.CombinedLayer) CustomLayer(org.pepsoft.worldpainter.layers.CustomLayer) CombinedLayer(org.pepsoft.worldpainter.layers.CombinedLayer) Layer(org.pepsoft.worldpainter.layers.Layer) NotNull(org.jetbrains.annotations.NotNull)

Example 3 with CombinedLayer

use of org.pepsoft.worldpainter.layers.CombinedLayer in project WorldPainter by Captain-Chaos.

the class CombinedLayerPaint method applyPixel.

@Override
public void applyPixel(Dimension dimension, int x, int y) {
    final Tile tile = dimension.getTileForEditing(x >> TILE_SIZE_BITS, y >> TILE_SIZE_BITS);
    if (tile != null) {
        final int xInTile = x & TILE_SIZE_MASK, yInTile = y & TILE_SIZE_MASK;
        final int value = 1 + (int) (brush.getLevel() * 14 + 0.5f);
        if (tile.getLayerValue(layer, xInTile, yInTile) < value) {
            tile.setLayerValue(layer, xInTile, yInTile, value);
        }
        final Terrain terrain = ((CombinedLayer) layer).getTerrain();
        if (terrain != null) {
            tile.setTerrain(xInTile, yInTile, terrain);
        }
        final int biome = ((CombinedLayer) layer).getBiome();
        if (biome != -1) {
            tile.setLayerValue(Biome.INSTANCE, xInTile, yInTile, biome);
        }
    }
}
Also used : CombinedLayer(org.pepsoft.worldpainter.layers.CombinedLayer) Terrain(org.pepsoft.worldpainter.Terrain) Tile(org.pepsoft.worldpainter.Tile)

Aggregations

CombinedLayer (org.pepsoft.worldpainter.layers.CombinedLayer)3 Terrain (org.pepsoft.worldpainter.Terrain)2 Tile (org.pepsoft.worldpainter.Tile)2 NotNull (org.jetbrains.annotations.NotNull)1 CustomLayer (org.pepsoft.worldpainter.layers.CustomLayer)1 Layer (org.pepsoft.worldpainter.layers.Layer)1