/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package org.pepsoft.worldpainter.themes.impl.fancy; import org.pepsoft.minecraft.Constants; import org.pepsoft.worldpainter.HeightMap; import org.pepsoft.worldpainter.HeightTransform; import org.pepsoft.worldpainter.MixedMaterial; import org.pepsoft.worldpainter.Terrain; import org.pepsoft.worldpainter.Tile; import org.pepsoft.worldpainter.heightMaps.ConstantHeightMap; import org.pepsoft.worldpainter.heightMaps.NoiseHeightMap; import org.pepsoft.worldpainter.heightMaps.SumHeightMap; import org.pepsoft.worldpainter.layers.DeciduousForest; import org.pepsoft.worldpainter.layers.Frost; import org.pepsoft.worldpainter.layers.Jungle; import org.pepsoft.worldpainter.layers.PineForest; import org.pepsoft.worldpainter.layers.SwampLand; import org.pepsoft.worldpainter.layers.groundcover.GroundCoverLayer; import org.pepsoft.worldpainter.themes.Theme; import java.util.Random; /** * * @author SchmitzP */ public class FancyTheme implements Theme, Cloneable { public FancyTheme(int maxHeight, int waterHeight, HeightMap heightMap, Terrain baseTerrain) { setMaxHeight(maxHeight); setWaterHeight(waterHeight); setHeightMap(heightMap); setDesertMaxHeight(waterHeight + 20); Random random = new Random(heightMap.getSeed()); setTemperatureMap(new SumHeightMap(new NoiseHeightMap(60f, 10.0, 2, random.nextLong()), new ConstantHeightMap(-20f))); setHumidityMap(new NoiseHeightMap(100f, 10.0, 2, random.nextLong())); setForestMap(new NoiseHeightMap(1f, 1.0, 3, random.nextLong())); setBaseTerrain(baseTerrain); snowLayer.setThickness(3); snowLayer.setEdgeWidth(3); snowLayer.setEdgeShape(GroundCoverLayer.EdgeShape.LINEAR); } @Override public void apply(Tile tile, int x, int y) { final int worldX = (tile.getX() << 7) | x, worldY = (tile.getY() << 7) | y; float temperature = temperatureMap.getHeight(worldX, worldY); float height = tile.getHeight(x, y); temperature = temperature - Math.max(height - waterHeight, 0) / 2f + randomNoiseMap.getHeight(worldX, worldY); float humidity = humidityMap.getHeight(worldX, worldY) + randomNoiseMap.getHeight(worldX, worldY); final float slopeNOSO = Math.abs(heightMap.getHeight( worldX, worldY - 1) - heightMap.getHeight( worldX, worldY + 1)); final float slopeNWSE = Math.abs(heightMap.getHeight(worldX + 1, worldY - 1) - heightMap.getHeight(worldX - 1, worldY + 1)); final float slopeEAWE = Math.abs(heightMap.getHeight(worldX + 1, worldY) - heightMap.getHeight(worldX - 1, worldY)); final float slopeSENW = Math.abs(heightMap.getHeight(worldX + 1, worldY + 1) - heightMap.getHeight(worldX - 1, worldY - 1)); final float slope = Math.max(Math.max(slopeNOSO, slopeNWSE), Math.max(slopeEAWE, slopeSENW)); if (slope > 2f) { tile.setTerrain(x, y, TERRAIN_STONE_AND_GRAVEL); } else { if (slope > 1.5f) { tile.setTerrain(x, y, TERRAIN_DIRT_AND_GRAVEL); } else if (height < (waterHeight - 4)) { tile.setTerrain(x, y, Terrain.BEACHES); } else if ((height < (waterHeight + 2)) && isWaterNear(worldX, worldY)) { tile.setTerrain(x, y, Terrain.BEACHES); if ((temperature > 20) && (humidity > 55) && (slope < 0.75f) && (height < desertMaxHeight) && (forestMap.getHeight(worldX, worldY) > 0.35f)) { tile.setLayerValue(Jungle.INSTANCE, x, y, 8); } } else if (temperature < -5) { tile.setTerrain(x, y, Terrain.BARE_GRASS); } else if (humidity < 40) { if ((slope < 0.75f) && (height < desertMaxHeight)) { tile.setTerrain(x, y, Terrain.DESERT); } else { tile.setTerrain(x, y, Terrain.SANDSTONE); } } else { tile.setTerrain(x, y, baseTerrain); } if ((height > (waterHeight - 4)) && (forestMap.getHeight(worldX, worldY) > 0.35f)) { if (temperature > 20) { if (humidity > 55) { if (height < waterHeight + 2) { tile.setLayerValue(SwampLand.INSTANCE, x, y, 8); } else { tile.setLayerValue(Jungle.INSTANCE, x, y, 8); } } else if (humidity > 40) { tile.setLayerValue(DeciduousForest.INSTANCE, x, y, 8); } } else if (temperature > 10) { if (humidity > 50) { tile.setLayerValue(DeciduousForest.INSTANCE, x, y, 8); } } else if (temperature > -20) { if (humidity > 50) { tile.setLayerValue(PineForest.INSTANCE, x, y, 8); } } } } if (temperature < 0) { tile.setBitLayerValue(Frost.INSTANCE, x, y, true); if ((temperature < -10) && (humidity > 50) && (height > waterHeight) && (slope < 1.5f)) { tile.setBitLayerValue(snowLayer, x, y, true); } } } @Override public final int getWaterHeight() { return waterHeight; } @Override public final void setWaterHeight(int waterLevel) { this.waterHeight = waterLevel; } @Override public final int getMaxHeight() { return maxHeight; } public final void setMaxHeight(int maxHeight) { setMaxHeight(maxHeight, HeightTransform.IDENTITY); } @Override public final void setMaxHeight(int maxHeight, HeightTransform transform) { this.maxHeight = maxHeight; } @Override public final long getSeed() { return humidityMap.getSeed(); } @Override public final void setSeed(long seed) { humidityMap.setSeed(seed); temperatureMap.setSeed(seed); } public final HeightMap getHumidityMap() { return humidityMap; } public final void setHumidityMap(HeightMap humidityMap) { this.humidityMap = humidityMap; } public final HeightMap getTemperatureMap() { return temperatureMap; } public final void setTemperatureMap(HeightMap temperatureMap) { this.temperatureMap = temperatureMap; } public final HeightMap getHeightMap() { return heightMap; } public final void setHeightMap(HeightMap heightMap) { this.heightMap = heightMap; } public final float getRockySlope() { return rockySlope; } public final void setRockySlope(float rockySlope) { this.rockySlope = rockySlope; } public final int getDesertMaxHeight() { return desertMaxHeight; } public final void setDesertMaxHeight(int desertMaxHeight) { this.desertMaxHeight = desertMaxHeight; } public final HeightMap getForestMap() { return forestMap; } public final void setForestMap(HeightMap forestMap) { this.forestMap = forestMap; } public final Terrain getBaseTerrain() { return baseTerrain; } public final void setBaseTerrain(Terrain baseTerrain) { this.baseTerrain = baseTerrain; } @Override public Theme clone() { try { FancyTheme clone = (FancyTheme) super.clone(); clone.forestMap = forestMap.clone(); clone.heightMap = heightMap.clone(); clone.humidityMap = humidityMap.clone(); return clone; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } private boolean isWaterNear(int x, int y) { if (heightMap.getHeight(x, y) < waterHeight) { return true; } for (int dx = -5; dx <= 5; dx++) { for (int dy = -5; dy <= 5; dy++) { if (heightMap.getHeight(x + dx, y + dy) < waterHeight) { return true; } } } return false; } private int maxHeight, waterHeight, desertMaxHeight; /** * Humidity in %. */ private HeightMap humidityMap; /** * Temperature in °C. */ private HeightMap temperatureMap; private HeightMap heightMap; private float rockySlope = 1.5f; private HeightMap forestMap; private Terrain baseTerrain; private final HeightMap randomNoiseMap = new SumHeightMap(new ConstantHeightMap(-5f), new NoiseHeightMap(10f, 1.0, 3)); private final GroundCoverLayer snowLayer = new GroundCoverLayer("Deep Snow", MixedMaterial.create(Constants.BLK_SNOW_BLOCK), 0xffffff); private static final Terrain TERRAIN_DIRT_AND_GRAVEL = Terrain.CUSTOM_1; private static final Terrain TERRAIN_STONE_AND_GRAVEL = Terrain.CUSTOM_2; private static final long serialVersionUID = 1L; }