@Override public void setHeight(int x, int z, int height) { if (readOnly) { return; } heightMap[x + z * 16] = (byte) (Math.min(height, 255)); }
@Override public void paintTile( final Image tileImage, final int x, final int y, final int imageX, final int imageY) { try { if (zoom == 0) { paintUnzoomedTile(tileImage, x, y, imageX, imageY); } else { Graphics2D g2 = (Graphics2D) tileImage.getGraphics(); try { BufferedImage surroundingTileImage = null; final Color waterColour = new Color(colourScheme.getColour(BLK_WATER)); final Color lavaColour = new Color(colourScheme.getColour(BLK_LAVA)); final Color voidColour = new Color(VoidRenderer.getColour()); final Color bedrockColour = new Color(colourScheme.getColour(BLK_BEDROCK)); final int scale = 1 << -zoom; final int subSize = TILE_SIZE / scale; for (int dx = 0; dx < scale; dx++) { for (int dy = 0; dy < scale; dy++) { TileType tileType = getUnzoomedTileType(x * scale + dx, y * scale + dy); switch (tileType) { case WORLD: Tile tile = tileProvider.getTile(x * scale + dx, y * scale + dy); if (tile.hasLayer(NotPresent.INSTANCE)) { if (surroundingTileProvider != null) { if (surroundingTileImage == null) { surroundingTileImage = new BufferedImage(TILE_SIZE, TILE_SIZE, BufferedImage.TYPE_INT_ARGB); surroundingTileProvider.paintTile(surroundingTileImage, x, y, 0, 0); } g2.drawImage( surroundingTileImage, imageX + dx * subSize, imageY + dy * subSize, imageX + (dx + 1) * subSize, imageY + (dy + 1) * subSize, imageX + dx * subSize, imageY + dy * subSize, imageX + (dx + 1) * subSize, imageY + (dy + 1) * subSize, null); } else { g2.setColor(voidColour); g2.fillRect(imageX + dx * subSize, imageY + dy * subSize, subSize, subSize); } } TileRenderer tileRenderer = tileRendererRef.get(); tileRenderer.setTile(tile); tileRenderer.renderTile(tileImage, dx * subSize, dy * subSize); break; case BORDER: Color colour; switch (((Dimension) tileProvider).getBorder()) { case WATER: colour = waterColour; break; case LAVA: colour = lavaColour; break; case VOID: colour = voidColour; break; default: throw new InternalError(); } g2.setColor(colour); g2.fillRect(imageX + dx * subSize, imageY + dy * subSize, subSize, subSize); // Draw border lines g2.setColor(Color.BLACK); g2.setStroke( new BasicStroke( 2, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0.0f, new float[] {4.0f, 4.0f}, 0.0f)); if (tileProvider.isTilePresent(x * scale + dx, y * scale + dy - 1)) { g2.drawLine( imageX + dx * subSize, imageY + dy * subSize, imageX + (dx + 1) * subSize - 1, imageY + dy * subSize); } if (tileProvider.isTilePresent(x * scale + dx + 1, y * scale + dy)) { g2.drawLine( imageX + (dx + 1) * subSize - 1, imageY + dy * subSize, imageX + (dx + 1) * subSize - 1, imageY + (dy + 1) * subSize - 1); } if (tileProvider.isTilePresent(x * scale + dx, y * scale + dy + 1)) { g2.drawLine( imageX + dx * subSize, imageY + (dy + 1) * subSize - 1, imageX + (dx + 1) * subSize - 1, imageY + (dy + 1) * subSize - 1); } if (tileProvider.isTilePresent(x * scale + dx - 1, y * scale + dy)) { g2.drawLine( imageX + dx * subSize, imageY + dy * subSize, imageX + dx * subSize, imageY + (dy + 1) * subSize - 1); } break; case SURROUNDS: case WALL: if (surroundingTileProvider != null) { if (surroundingTileImage == null) { surroundingTileImage = new BufferedImage(TILE_SIZE, TILE_SIZE, BufferedImage.TYPE_INT_ARGB); surroundingTileProvider.paintTile(surroundingTileImage, x, y, 0, 0); } g2.drawImage( surroundingTileImage, imageX + dx * subSize, imageY + dy * subSize, imageX + (dx + 1) * subSize, imageY + (dy + 1) * subSize, imageX + dx * subSize, imageY + dy * subSize, imageX + (dx + 1) * subSize, imageY + (dy + 1) * subSize, null); } else { g2.setColor(voidColour); g2.fillRect(imageX + dx * subSize, imageY + dy * subSize, subSize, subSize); } if (tileType == TileType.WALL) { g2.setColor(bedrockColour); TileType neighbourType = getUnzoomedTileType(x * scale + dx, y * scale + dy - 1); int wallWidth = Math.max(subSize / 8, 1); if ((neighbourType == TileType.WORLD) || (neighbourType == TileType.BORDER)) { g2.fillRect(imageX + dx * subSize, imageY + dy * subSize, subSize, wallWidth); } neighbourType = getUnzoomedTileType(x * scale + dx + 1, y * scale + dy); if ((neighbourType == TileType.WORLD) || (neighbourType == TileType.BORDER)) { g2.fillRect( imageX + (dx + 1) * subSize - wallWidth, imageY + dy * subSize, wallWidth, subSize); } neighbourType = getUnzoomedTileType(x * scale + dx, y * scale + dy + 1); if ((neighbourType == TileType.WORLD) || (neighbourType == TileType.BORDER)) { g2.fillRect( imageX + dx * subSize, imageY + (dy + 1) * subSize - wallWidth, subSize, wallWidth); } neighbourType = getUnzoomedTileType(x * scale + dx - 1, y * scale + dy); if ((neighbourType == TileType.WORLD) || (neighbourType == TileType.BORDER)) { g2.fillRect(imageX + dx * subSize, imageY + dy * subSize, wallWidth, subSize); } } break; } } } } finally { g2.dispose(); } } } catch (Throwable e) { // Log at debug level because this tends to happen when zooming in // and out, probably due to some state getting out of sync. It // doesn't so far appear to have any visible consequences. logger.error("Exception while generating image for tile at " + x + ", " + y, e); } }