Search in sources :

Example 1 with Tile

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

the class IntegrityChecker method main.

public static void main(String[] args) throws IOException, ClassNotFoundException {
    System.out.println("Loading " + args[0]);
    World2 world;
    try (ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(new FileInputStream(args[0])))) {
        world = (World2) in.readObject();
    }
    for (Dimension dimension : world.getDimensions()) {
        float maxHeight = (dimension.getMaxHeight() - 1) + 0.5f;
        System.out.println("Checking integrity of " + dimension.getName() + " dimension");
        for (Tile tile : dimension.getTiles()) {
            boolean tileReported = false;
            for (int x = 0; x < Constants.TILE_SIZE; x++) {
                for (int y = 0; y < Constants.TILE_SIZE; y++) {
                    float height = tile.getHeight(x, y);
                    if (height < -0.5f) {
                        if (!tileReported) {
                            System.out.println("Tile " + tile.getX() + "," + tile.getY());
                            tileReported = true;
                        }
                        System.out.println("Height " + height + " < -0.5 @ " + x + "," + y);
                    } else if (height > maxHeight) {
                        if (!tileReported) {
                            System.out.println("Tile " + tile.getX() + "," + tile.getY());
                            tileReported = true;
                        }
                        System.out.println("Height " + height + " > " + maxHeight + " @ " + x + "," + y);
                    }
                }
            }
        }
    }
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) World2(org.pepsoft.worldpainter.World2) Tile(org.pepsoft.worldpainter.Tile) Dimension(org.pepsoft.worldpainter.Dimension) FileInputStream(java.io.FileInputStream) ObjectInputStream(java.io.ObjectInputStream)

Example 2 with Tile

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

the class ResetLava method main.

public static void main(String[] args) throws IOException, ClassNotFoundException {
    System.out.println("Loading world " + args[0]);
    File worldFile = new File(args[0]);
    int waterLevel = Integer.parseInt(args[1]);
    World2 world;
    try (ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(new FileInputStream(worldFile)))) {
        world = (World2) in.readObject();
    }
    System.out.println("World loaded");
    Dimension dim0 = world.getDimension(0);
    for (Tile tile : dim0.getTiles()) {
        for (int x = 0; x < TILE_SIZE; x++) {
            for (int y = 0; y < TILE_SIZE; y++) {
                // if ((tile.getWaterLevel(x, y) > (tile.getIntHeight(x, y))) && tile.getBitLayerValue(FloodWithLava.INSTANCE, x, y)) {
                tile.setBitLayerValue(FloodWithLava.INSTANCE, x, y, false);
                tile.setWaterLevel(x, y, waterLevel);
            // }
            }
        }
        System.out.print('.');
    }
    System.out.println();
    System.out.println("Saving world " + args[0]);
    try (ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(worldFile)))) {
        out.writeObject(world);
    }
    System.out.println("World saved");
}
Also used : GZIPInputStream(java.util.zip.GZIPInputStream) GZIPOutputStream(java.util.zip.GZIPOutputStream) World2(org.pepsoft.worldpainter.World2) FileOutputStream(java.io.FileOutputStream) Tile(org.pepsoft.worldpainter.Tile) Dimension(org.pepsoft.worldpainter.Dimension) ObjectOutputStream(java.io.ObjectOutputStream) File(java.io.File) FileInputStream(java.io.FileInputStream) ObjectInputStream(java.io.ObjectInputStream)

Example 3 with Tile

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

the class MaskImporter method doImport.

public void doImport(ProgressReceiver progressReceiver) throws ProgressReceiver.OperationCancelled {
    if ((!applyToTerrain) && (applyToLayer == null)) {
        throw new IllegalStateException("Target not set");
    }
    if (mapping == null) {
        throw new IllegalStateException("Mapping not set");
    }
    if ((mapping == Mapping.THRESHOLD) && (threshold == -1)) {
        throw new IllegalStateException("Threshold not set");
    }
    final int maxValue;
    switch(inputType) {
        case ONE_BIT_GRAY_SCALE:
            maxValue = 1;
            break;
        case EIGHT_BIT_GREY_SCALE:
            maxValue = 255;
            break;
        case SIXTEEN_BIT_GREY_SCALE:
            maxValue = 65535;
            break;
        default:
            maxValue = 0;
            break;
    }
    final Random random = new Random(dimension.getSeed() + xOffset * 31 + yOffset);
    // Scale the mask, if necessary
    final BufferedImage scaledImage;
    if (scale == 100) {
        // No scaling necessary
        scaledImage = image;
    } else {
        final int newWidth = image.getWidth() * scale / 100, newHeight = image.getHeight() * scale / 100;
        if (image.getColorModel() instanceof IndexColorModel) {
            scaledImage = new BufferedImage(newWidth, newHeight, image.getType(), (IndexColorModel) image.getColorModel());
        } else {
            scaledImage = new BufferedImage(newWidth, newHeight, image.getType());
        }
        Graphics2D g2 = scaledImage.createGraphics();
        try {
            if (mapping == Mapping.FULL_RANGE) {
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
            }
            g2.drawImage(image, 0, 0, newWidth, newHeight, null);
        } finally {
            g2.dispose();
        }
    }
    // The original image is no longer necessary, so allow it to be garbage collected to make more space available for the import
    image = null;
    // Create the appropriate mapping logic
    abstract class Applicator {

        void setTile(Tile tile) {
            this.tile = tile;
        }

        abstract void apply(int x, int y, int value);

        Tile tile;
    }
    final Applicator applicator;
    final String aspect;
    switch(inputType) {
        case ONE_BIT_GRAY_SCALE:
            if (removeExistingLayer) {
                applicator = new Applicator() {

                    @Override
                    void apply(int x, int y, int value) {
                        tile.setBitLayerValue(applyToLayer, x, y, value != 0);
                    }
                };
            } else {
                applicator = new Applicator() {

                    @Override
                    void apply(int x, int y, int value) {
                        if (value != 0) {
                            tile.setBitLayerValue(applyToLayer, x, y, true);
                        }
                    }
                };
            }
            aspect = "layer " + applyToLayer.getName();
            break;
        case EIGHT_BIT_GREY_SCALE:
        case SIXTEEN_BIT_GREY_SCALE:
            switch(mapping) {
                case ONE_TO_ONE:
                    if (applyToTerrain) {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                tile.setTerrain(x, y, Terrain.VALUES[value]);
                            }
                        };
                        aspect = "terrain";
                    } else {
                        final int defaultValue = applyToLayer.getDefaultValue();
                        if (removeExistingLayer) {
                            applicator = new Applicator() {

                                @Override
                                void apply(int x, int y, int value) {
                                    if ((value != defaultValue) || (tile.getLayerValue(applyToLayer, x, y) != defaultValue)) {
                                        tile.setLayerValue(applyToLayer, x, y, value);
                                    }
                                }
                            };
                        } else {
                            applicator = new Applicator() {

                                @Override
                                void apply(int x, int y, int value) {
                                    if ((value != defaultValue) && (value > tile.getLayerValue(applyToLayer, x, y))) {
                                        tile.setLayerValue(applyToLayer, x, y, value);
                                    }
                                }
                            };
                        }
                        aspect = "layer " + applyToLayer.getName();
                    }
                    break;
                case DITHERING:
                    if (removeExistingLayer) {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                boolean layerValue = (value > 0) && (random.nextInt(limit) <= value);
                                if (layerValue || (tile.getBitLayerValue(applyToLayer, x, y))) {
                                    tile.setBitLayerValue(applyToLayer, x, y, layerValue);
                                }
                            }

                            private final int limit = maxValue + 1;
                        };
                    } else {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                if ((value > 0) && (random.nextInt(limit) <= value)) {
                                    tile.setBitLayerValue(applyToLayer, x, y, true);
                                }
                            }

                            private final int limit = maxValue + 1;
                        };
                    }
                    aspect = "layer " + applyToLayer.getName();
                    break;
                case THRESHOLD:
                    if (removeExistingLayer) {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                boolean layerValue = value >= threshold;
                                if (layerValue || tile.getBitLayerValue(applyToLayer, x, y)) {
                                    tile.setBitLayerValue(applyToLayer, x, y, layerValue);
                                }
                            }
                        };
                    } else {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                if (value >= threshold) {
                                    tile.setBitLayerValue(applyToLayer, x, y, true);
                                }
                            }
                        };
                    }
                    aspect = "layer " + applyToLayer.getName();
                    break;
                case FULL_RANGE:
                    final int layerLimit;
                    if (applyToLayer.getDataSize() == Layer.DataSize.NIBBLE) {
                        layerLimit = 16;
                    } else if (applyToLayer.getDataSize() == Layer.DataSize.BYTE) {
                        layerLimit = 256;
                    } else {
                        throw new IllegalArgumentException();
                    }
                    final int defaultValue = applyToLayer.getDefaultValue();
                    if (removeExistingLayer) {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                int layerValue = value * layerLimit / limit;
                                if ((layerValue != defaultValue) || (tile.getLayerValue(applyToLayer, x, y) != defaultValue)) {
                                    tile.setLayerValue(applyToLayer, x, y, layerValue);
                                }
                            }

                            private final int limit = maxValue + 1;
                        };
                    } else {
                        applicator = new Applicator() {

                            @Override
                            void apply(int x, int y, int value) {
                                int layerValue = value * layerLimit / limit;
                                if ((layerValue != defaultValue) && (layerValue > tile.getLayerValue(applyToLayer, x, y))) {
                                    tile.setLayerValue(applyToLayer, x, y, layerValue);
                                }
                            }

                            private final int limit = maxValue + 1;
                        };
                    }
                    aspect = "layer " + applyToLayer.getName();
                    break;
                default:
                    throw new IllegalArgumentException("Don't know how to apply this combo");
            }
            break;
        case COLOUR:
            if (removeExistingLayer) {
                applicator = new Applicator() {

                    @Override
                    void apply(int x, int y, int value) {
                        if (((value >> 24) & 0xff) > 0x7f) {
                            tile.setLayerValue(Annotations.INSTANCE, x, y, COLOUR_ANNOTATION_MAPPING[((value >> 12) & 0xf00) | ((value >> 8) & 0xf0) | ((value >> 4) & 0xf)]);
                        } else if (tile.getLayerValue(Annotations.INSTANCE, x, y) != 0) {
                            tile.setLayerValue(Annotations.INSTANCE, x, y, 0);
                        }
                    }
                };
            } else {
                applicator = new Applicator() {

                    @Override
                    void apply(int x, int y, int value) {
                        if (((value >> 24) & 0xff) > 0x7f) {
                            tile.setLayerValue(Annotations.INSTANCE, x, y, COLOUR_ANNOTATION_MAPPING[((value >> 12) & 0xf00) | ((value >> 8) & 0xf0) | ((value >> 4) & 0xf)]);
                        }
                    }
                };
            }
            aspect = "annotations";
            break;
        default:
            throw new IllegalArgumentException("Don't know how to apply this combo");
    }
    if (dimension.getWorld() != null) {
        dimension.getWorld().addHistoryEntry(HistoryEntry.WORLD_MASK_IMPORTED_TO_DIMENSION, dimension.getName(), imageFile, aspect);
    }
    // Apply the mask tile by tile
    final int width = scaledImage.getWidth(), height = scaledImage.getHeight();
    final int tileX1 = xOffset >> TILE_SIZE_BITS, tileX2 = (xOffset + width - 1) >> TILE_SIZE_BITS;
    final int tileY1 = yOffset >> TILE_SIZE_BITS, tileY2 = (yOffset + height - 1) >> TILE_SIZE_BITS;
    final int noOfTiles = (tileX2 - tileX1 + 1) * (tileY2 - tileY1 + 1);
    int tileCount = 0;
    for (int tileX = tileX1; tileX <= tileX2; tileX++) {
        for (int tileY = tileY1; tileY <= tileY2; tileY++) {
            final Tile tile = dimension.getTile(tileX, tileY);
            if (tile == null) {
                tileCount++;
                if (progressReceiver != null) {
                    progressReceiver.setProgress((float) tileCount / noOfTiles);
                }
                continue;
            }
            tile.inhibitEvents();
            try {
                final int tileOffsetX = (tileX << TILE_SIZE_BITS) - xOffset, tileOffsetY = (tileY << TILE_SIZE_BITS) - yOffset;
                final Raster raster = scaledImage.getRaster();
                applicator.setTile(tile);
                if (inputType == InputType.COLOUR) {
                    for (int xInTile = 0; xInTile < TILE_SIZE; xInTile++) {
                        for (int yInTile = 0; yInTile < TILE_SIZE; yInTile++) {
                            final int imageX = tileOffsetX + xInTile, imageY = tileOffsetY + yInTile;
                            if ((imageX >= 0) && (imageX < width) && (imageY >= 0) && (imageY < height)) {
                                applicator.apply(xInTile, yInTile, scaledImage.getRGB(imageX, imageY));
                            }
                        }
                    }
                } else {
                    for (int xInTile = 0; xInTile < TILE_SIZE; xInTile++) {
                        for (int yInTile = 0; yInTile < TILE_SIZE; yInTile++) {
                            final int imageX = tileOffsetX + xInTile, imageY = tileOffsetY + yInTile;
                            if ((imageX >= 0) && (imageX < width) && (imageY >= 0) && (imageY < height)) {
                                applicator.apply(xInTile, yInTile, raster.getSample(imageX, imageY, 0));
                            }
                        }
                    }
                }
            } finally {
                tile.releaseEvents();
            }
            tileCount++;
            if (progressReceiver != null) {
                progressReceiver.setProgress((float) tileCount / noOfTiles);
            }
        }
    }
}
Also used : Raster(java.awt.image.Raster) Tile(org.pepsoft.worldpainter.Tile) BufferedImage(java.awt.image.BufferedImage) IndexColorModel(java.awt.image.IndexColorModel)

Example 4 with Tile

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

the class CombinedLayerPaint method removePixel.

@Override
public void removePixel(Dimension dimension, int x, int y) {
    if (((CombinedLayer) layer).getTerrain() != null) {
        // applyTheme() only exists at Dimension-level, so go via the dimension
        dimension.setLayerValueAt(layer, x, y, 0);
        dimension.applyTheme(x, y);
        if (((CombinedLayer) layer).getBiome() != -1) {
            dimension.setLayerValueAt(Biome.INSTANCE, x, y, 255);
        }
    } else {
        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;
            tile.setLayerValue(layer, xInTile, yInTile, 0);
            if (((CombinedLayer) layer).getBiome() != -1) {
                tile.setLayerValue(Biome.INSTANCE, xInTile, yInTile, 255);
            }
        }
    }
}
Also used : Tile(org.pepsoft.worldpainter.Tile)

Example 5 with Tile

use of org.pepsoft.worldpainter.Tile 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)

Aggregations

Tile (org.pepsoft.worldpainter.Tile)31 Dimension (org.pepsoft.worldpainter.Dimension)6 CombinedLayer (org.pepsoft.worldpainter.layers.CombinedLayer)5 Point (java.awt.Point)4 FileOutputStream (java.io.FileOutputStream)4 Terrain (org.pepsoft.worldpainter.Terrain)4 World2 (org.pepsoft.worldpainter.World2)4 Rectangle (java.awt.Rectangle)3 BufferedImage (java.awt.image.BufferedImage)3 File (java.io.File)3 FileInputStream (java.io.FileInputStream)3 ObjectInputStream (java.io.ObjectInputStream)3 GZIPInputStream (java.util.zip.GZIPInputStream)3 SubProgressReceiver (org.pepsoft.util.SubProgressReceiver)3 Layer (org.pepsoft.worldpainter.layers.Layer)3 Graphics2D (java.awt.Graphics2D)2 ObjectOutputStream (java.io.ObjectOutputStream)2 PrintWriter (java.io.PrintWriter)2 java.util (java.util)2 List (java.util.List)2