Search in sources :

Example 1 with Border

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

the class BorderChunkFactory method create.

public static ChunkFactory.ChunkCreationResult create(int chunkX, int chunkZ, Dimension dimension, Map<Layer, LayerExporter> exporters) {
    final int maxHeight = dimension.getMaxHeight();
    final Platform platform = dimension.getWorld().getPlatform();
    final Border border = dimension.getBorder();
    final int borderLevel = dimension.getBorderLevel();
    final boolean dark = dimension.isDarkLevel();
    final boolean bottomless = dimension.isBottomless();
    final Terrain subsurfaceMaterial = dimension.getSubsurfaceMaterial();
    final PerlinNoise noiseGenerator;
    if (noiseGenerators.get() == null) {
        noiseGenerator = new PerlinNoise(0);
        noiseGenerators.set(noiseGenerator);
    } else {
        noiseGenerator = noiseGenerators.get();
    }
    final long seed = dimension.getSeed();
    if (noiseGenerator.getSeed() != seed) {
        noiseGenerator.setSeed(seed);
    }
    final int floor = Math.max(borderLevel - 20, 0);
    final int variation = Math.min(15, (borderLevel - floor) / 2);
    final ChunkFactory.ChunkCreationResult result = new ChunkFactory.ChunkCreationResult();
    result.chunk = PlatformManager.getInstance().createChunk(platform, chunkX, chunkZ, maxHeight);
    final int maxY = maxHeight - 1;
    if (platform.capabilities.contains(BIOMES)) {
        switch(border) {
            case VOID:
            case LAVA:
                for (int x = 0; x < 16; x++) {
                    for (int z = 0; z < 16; z++) {
                        result.chunk.setBiome(x, z, BIOME_PLAINS);
                    }
                }
                break;
            case WATER:
                for (int x = 0; x < 16; x++) {
                    for (int z = 0; z < 16; z++) {
                        result.chunk.setBiome(x, z, BIOME_OCEAN);
                    }
                }
                break;
            default:
                throw new InternalError();
        }
    }
    for (int x = 0; x < 16; x++) {
        for (int z = 0; z < 16; z++) {
            if (border != Border.VOID) {
                final int worldX = (chunkX << 4) | x, worldZ = (chunkZ << 4) | z;
                final int floorLevel = (int) (floor + (noiseGenerator.getPerlinNoise(worldX / MEDIUM_BLOBS, worldZ / MEDIUM_BLOBS) + 0.5f) * variation + 0.5f);
                final int surfaceLayerLevel = floorLevel - dimension.getTopLayerDepth(worldX, worldZ, floorLevel);
                for (int y = 0; y <= maxY; y++) {
                    if ((y == 0) && (!bottomless)) {
                        result.chunk.setBlockType(x, y, z, BLK_BEDROCK);
                    } else if (y <= surfaceLayerLevel) {
                        result.chunk.setMaterial(x, y, z, subsurfaceMaterial.getMaterial(seed, worldX, worldZ, y, floorLevel));
                    } else if (y <= floorLevel) {
                        result.chunk.setMaterial(x, y, z, BEACHES.getMaterial(seed, worldX, worldZ, y, floorLevel));
                    } else if (y <= borderLevel) {
                        switch(border) {
                            case WATER:
                                result.chunk.setBlockType(x, y, z, BLK_STATIONARY_WATER);
                                break;
                            case LAVA:
                                result.chunk.setBlockType(x, y, z, BLK_STATIONARY_LAVA);
                                break;
                            default:
                        }
                    }
                }
            }
            if (dark) {
                result.chunk.setBlockType(x, maxY, z, BLK_BEDROCK);
                result.chunk.setHeight(x, z, maxY);
            } else if (border == Border.VOID) {
                result.chunk.setHeight(x, z, 0);
            } else {
                result.chunk.setHeight(x, z, (borderLevel < maxY) ? (borderLevel + 1) : maxY);
            }
        }
    }
    if (border != Border.VOID) {
        // Apply layers set to be applied everywhere, if any
        final Set<Layer> minimumLayers = dimension.getMinimumLayers();
        if (!minimumLayers.isEmpty()) {
            Tile virtualTile = new Tile(chunkX >> 3, chunkZ >> 3, dimension.getMaxHeight()) {

                @Override
                public synchronized float getHeight(int x, int y) {
                    return floor + (noiseGenerator.getPerlinNoise(((getX() << TILE_SIZE_BITS) | x) / MEDIUM_BLOBS, ((getY() << TILE_SIZE_BITS) | y) / MEDIUM_BLOBS) + 0.5f) * variation;
                }

                @Override
                public synchronized int getWaterLevel(int x, int y) {
                    return borderLevel;
                }

                private static final long serialVersionUID = 1L;
            };
            for (Layer layer : minimumLayers) {
                LayerExporter layerExporter = exporters.get(layer);
                if (layerExporter instanceof FirstPassLayerExporter) {
                    ((FirstPassLayerExporter) layerExporter).render(dimension, virtualTile, result.chunk);
                }
            }
        }
    }
    result.chunk.setTerrainPopulated(true);
    result.stats.surfaceArea = 256;
    if ((border == Border.WATER) || (border == Border.LAVA)) {
        result.stats.waterArea = 256;
    }
    return result;
}
Also used : Platform(org.pepsoft.worldpainter.Platform) Tile(org.pepsoft.worldpainter.Tile) PerlinNoise(org.pepsoft.util.PerlinNoise) Layer(org.pepsoft.worldpainter.layers.Layer) Terrain(org.pepsoft.worldpainter.Terrain) Border(org.pepsoft.worldpainter.Dimension.Border) ChunkFactory(org.pepsoft.minecraft.ChunkFactory)

Aggregations

ChunkFactory (org.pepsoft.minecraft.ChunkFactory)1 PerlinNoise (org.pepsoft.util.PerlinNoise)1 Border (org.pepsoft.worldpainter.Dimension.Border)1 Platform (org.pepsoft.worldpainter.Platform)1 Terrain (org.pepsoft.worldpainter.Terrain)1 Tile (org.pepsoft.worldpainter.Tile)1 Layer (org.pepsoft.worldpainter.layers.Layer)1