Archived
0

World constants

This commit is contained in:
Forwolk
2018-08-01 11:02:45 +03:00
parent 4511fc40b1
commit a71d152528
2 changed files with 62 additions and 53 deletions

View File

@@ -13,6 +13,8 @@ import java.awt.image.BufferedImage;
import java.io.File; import java.io.File;
import java.util.UUID; import java.util.UUID;
import static mc.world.generated_world.WorldConstants.*;
public class SeedBasedWorldGenerator implements WorldGenerator { public class SeedBasedWorldGenerator implements WorldGenerator {
public static void main(String[] args) throws Exception{ public static void main(String[] args) throws Exception{
@@ -92,7 +94,6 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
private class RegionGenerator { private class RegionGenerator {
private final World world; private final World world;
private final Region region; private final Region region;
private final int size = 256;
private NoiseGenerator noiseGenerator; private NoiseGenerator noiseGenerator;
private BlockFactory blockFactory = new BlockFactory(); private BlockFactory blockFactory = new BlockFactory();
@@ -111,32 +112,32 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
noiseGenerator.init(); noiseGenerator.init();
File file = new File("out", region.getX() + "." + region.getZ()); File file = new File("out", region.getX() + "." + region.getZ());
file.mkdirs(); file.mkdirs();
int[][] heightMap = new int[size][size]; int[][] heightMap = new int[WorldConstants.WORLD_REGION_SIZE][WorldConstants.WORLD_REGION_SIZE];
int[][] grassMap = new int[size][size]; int[][] grassMap = new int[WorldConstants.WORLD_REGION_SIZE][WorldConstants.WORLD_REGION_SIZE];
int[][] temperatureMap = new int[size][size]; int[][] temperatureMap = new int[WorldConstants.WORLD_REGION_SIZE][WorldConstants.WORLD_REGION_SIZE];
int[][] wetMap = new int[size][size]; int[][] wetMap = new int[WorldConstants.WORLD_REGION_SIZE][WorldConstants.WORLD_REGION_SIZE];
Biome[][] biomes = new Biome[size][size]; Biome[][] biomes = new Biome[WorldConstants.WORLD_REGION_SIZE][WorldConstants.WORLD_REGION_SIZE];
for (int x = 0; x < size; x ++) { for (int x = 0; x < WorldConstants.WORLD_REGION_SIZE; x ++) {
for (int z = 0; z < size; z ++) { for (int z = 0; z < WorldConstants.WORLD_REGION_SIZE; z ++) {
int tx = convert(x + region.getX() * 256); int tx = convert(x + region.getX() * WorldConstants.WORLD_REGION_SIZE);
int tz = convert(z + region.getZ() * 256); int tz = convert(z + region.getZ() * WorldConstants.WORLD_REGION_SIZE);
double p = sigmoid(noiseGenerator.noise(tx / 53d, tz / 53d)); double p = sigmoid(noiseGenerator.noise(tx / WORLD_LAND_SIZE, tz / WORLD_LAND_SIZE));
double r = Math.sqrt(noiseGenerator.noise(tx / 6d, tz / 6d)); double r = Math.sqrt(noiseGenerator.noise(tx / WORLD_LAKE_SIZE, tz / WORLD_LAKE_SIZE));
double h = (WorldConstants.WORLD_MAX_HEIGHT - WorldConstants.WORLD_MIN_HEIGHT) * Math.min(p * r, 1); double h = (WORLD_MAX_HEIGHT - WORLD_MIN_HEIGHT) * Math.min(p * r, 1);
h = Math.min(WorldConstants.WORLD_MAX_HEIGHT, h + WorldConstants.WORLD_MIN_HEIGHT); h = Math.min(WORLD_MAX_HEIGHT, h + WORLD_MIN_HEIGHT);
heightMap[x][z] = (int)(h); heightMap[x][z] = (int)(h);
grassMap[x][z] = (int) (1 + SeedRandomGenerator.random(tx, tz, world.getSeed()) * (WorldConstants.LANDFILL_GRASS_SURFACE_THIN - 1)); grassMap[x][z] = (int) (1 + SeedRandomGenerator.random(tx, tz, world.getSeed()) * (LANDFILL_GRASS_SURFACE_THIN - 1));
double k = Math.sqrt(noiseGenerator.noise(tx * 2.99, tz * 2.99)); double k = Math.sqrt(noiseGenerator.noise(tx * WORLD_TEMPERATURE_GRAD_SIZE, tz * WORLD_TEMPERATURE_GRAD_SIZE));
double q = Math.sqrt(noiseGenerator.noise(tx / 41.0, tz / 41.0)); double q = Math.sqrt(noiseGenerator.noise(tx / WORLD_TEMPERATURE_SIZE, tz / WORLD_TEMPERATURE_SIZE));
temperatureMap[x][z] = (int) (100 * Math.min((k * k + q * q + k * q) * k * q, 0.99)); temperatureMap[x][z] = (int) (WORLD_MAX_TEMPERATURE * Math.min((k * k + q * q + k * q) * k * q, 0.99));
if (heightMap[x][z] < WorldConstants.WORLD_SEA_LEVEL) { if (heightMap[x][z] < WORLD_SEA_LEVEL) {
biomes[x][z] = Biome.OCEAN; biomes[x][z] = Biome.OCEAN;
wetMap[x][z] = 100; wetMap[x][z] = WORLD_MAX_WETNESS;
} }
} }
} }
for (int x = 1; x < size - 1; x ++) { for (int x = 1; x < WorldConstants.WORLD_REGION_SIZE - 1; x ++) {
for (int z = 1; z < size - 1; z++) { for (int z = 1; z < WorldConstants.WORLD_REGION_SIZE - 1; z++) {
int mid = 0; int mid = 0;
for (int tx = x - 1; tx <= x + 1; tx ++) { for (int tx = x - 1; tx <= x + 1; tx ++) {
for (int tz = z - 1; tz <= z + 1; tz ++) { for (int tz = z - 1; tz <= z + 1; tz ++) {
@@ -146,8 +147,8 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
wetMap[x][z] = mid / 9; wetMap[x][z] = mid / 9;
} }
} }
for (int z = 1; z < size - 1; z++) { for (int z = 1; z < WorldConstants.WORLD_REGION_SIZE - 1; z++) {
for (int x = 1; x < size - 1; x ++) { for (int x = 1; x < WorldConstants.WORLD_REGION_SIZE - 1; x ++) {
int mid = 0; int mid = 0;
for (int tx = x - 1; tx <= x + 1; tx ++) { for (int tx = x - 1; tx <= x + 1; tx ++) {
for (int tz = z - 1; tz <= z + 1; tz ++) { for (int tz = z - 1; tz <= z + 1; tz ++) {
@@ -158,9 +159,9 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} }
} }
for (int z = 1; z < size - 1; z++) { for (int z = 1; z < WorldConstants.WORLD_REGION_SIZE - 1; z++) {
for (int x = 1; x < size - 1; x ++) { for (int x = 1; x < WorldConstants.WORLD_REGION_SIZE - 1; x ++) {
wetMap[x][z] = (int) Math.min(100, 60 * noiseGenerator.noise(x / 31d, z / 67d) + wetMap[x][z] * (1 + 0.2 * SeedRandomGenerator.random(x, z, world.getSeed()))); wetMap[x][z] = (int) Math.min(WORLD_MAX_WETNESS, 60 * noiseGenerator.noise(x / 31d, z / 67d) + wetMap[x][z] * (1 + 0.2 * SeedRandomGenerator.random(x, z, world.getSeed())));
} }
} }
@@ -169,10 +170,10 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
smooth(wetMap); smooth(wetMap);
//smooth(heightMap); //smooth(heightMap);
for (int x = 0; x < 256; x ++) { for (int x = 0; x < WorldConstants.WORLD_REGION_SIZE; x ++) {
for (int z = 0; z < 256; z ++) { for (int z = 0; z < WorldConstants.WORLD_REGION_SIZE; z ++) {
Temperature temperature = Temperature.values()[temperatureMap[x][z] / 20]; Temperature temperature = Temperature.values()[Temperature.values().length * temperatureMap[x][z] / WORLD_MAX_TEMPERATURE];
Wetness wetness = Wetness.values()[(Math.min(wetMap[x][z], 100) - 1) / 100 * Wetness.values().length]; Wetness wetness = Wetness.values()[(Math.min(wetMap[x][z], 100) - 1) / WORLD_MAX_WETNESS * Wetness.values().length];
biomes[x][z] = selectBiome(temperature, wetness, heightMap[x][z]); biomes[x][z] = selectBiome(temperature, wetness, heightMap[x][z]);
} }
} }
@@ -218,11 +219,11 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} catch (Exception e) {} } catch (Exception e) {}
// ================================ DEBUG FINISH ======================================= // ================================ DEBUG FINISH =======================================
for (int x = 0; x < size; x ++) { for (int x = 0; x < WorldConstants.WORLD_REGION_SIZE; x ++) {
for (int z = 0; z < size; z ++) { for (int z = 0; z < WorldConstants.WORLD_REGION_SIZE; z ++) {
region.setBiome(x, z, biomes[x][z]); region.setBiome(x, z, biomes[x][z]);
if (heightMap[x][z] < WorldConstants.WORLD_SEA_LEVEL) { if (heightMap[x][z] < WORLD_SEA_LEVEL) {
for (int y = 0; y < WorldConstants.WORLD_SEA_LEVEL; y ++) { for (int y = 0; y < WORLD_SEA_LEVEL; y ++) {
Chunk chunk = region.getChunkAt(x / 16, y / 16, z / 16); Chunk chunk = region.getChunkAt(x / 16, y / 16, z / 16);
if (y == 0) { if (y == 0) {
chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0)); chunk.setBlock(x % 16, y % 16, z % 16, blockFactory.create(BlockType.BEDROCK, 0));
@@ -264,25 +265,25 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
private Biome selectBiome (Temperature temperature, Wetness wetness, int height) { private Biome selectBiome (Temperature temperature, Wetness wetness, int height) {
if (temperature == Temperature.FROST) { if (temperature == Temperature.FROST) {
if (height < WorldConstants.WORLD_SEA_LEVEL) { if (height < WORLD_SEA_LEVEL) {
return Biome.FROZEN_OCEAN; return Biome.FROZEN_OCEAN;
} else { } else {
if (height > (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MAX_HEIGHT) / 2) { if (height > (WORLD_SEA_LEVEL + WORLD_MAX_HEIGHT) / 2) {
return Biome.ICE_MOUNTAINS; return Biome.ICE_MOUNTAINS;
} else { } else {
return Biome.ICE_PLAINS; return Biome.ICE_PLAINS;
} }
} }
} }
if (height < WorldConstants.WORLD_SEA_LEVEL) { if (height < WORLD_SEA_LEVEL) {
if (height < (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MIN_HEIGHT) / 2){ if (height < (WORLD_SEA_LEVEL + WORLD_MIN_HEIGHT) / 2){
return Biome.DEEP_OCEAN; return Biome.DEEP_OCEAN;
} else { } else {
return Biome.OCEAN; return Biome.OCEAN;
} }
} }
if (temperature == Temperature.COLD) { if (temperature == Temperature.COLD) {
if (height > (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MAX_HEIGHT) / 2) { if (height > (WORLD_SEA_LEVEL + WORLD_MAX_HEIGHT) / 2) {
return Biome.TAIGA_HILLS; return Biome.TAIGA_HILLS;
} else { } else {
return Biome.TAIGA; return Biome.TAIGA;
@@ -294,7 +295,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} else if (wetness == Wetness.WATER){ } else if (wetness == Wetness.WATER){
return Biome.SWAMPLAND; return Biome.SWAMPLAND;
} else { } else {
if (height > (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MAX_HEIGHT) / 2) { if (height > (WORLD_SEA_LEVEL + WORLD_MAX_HEIGHT) / 2) {
return Biome.FOREST_HILLS; return Biome.FOREST_HILLS;
} else { } else {
return Biome.FOREST; return Biome.FOREST;
@@ -302,7 +303,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} }
} }
if (temperature == Temperature.HOTTEST && wetness.ordinal() < 2) { if (temperature == Temperature.HOTTEST && wetness.ordinal() < 2) {
if (height > (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MAX_HEIGHT) / 2) { if (height > (WORLD_SEA_LEVEL + WORLD_MAX_HEIGHT) / 2) {
return Biome.DESERT_HILLS; return Biome.DESERT_HILLS;
} else { } else {
return Biome.DESERT; return Biome.DESERT;
@@ -310,7 +311,7 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} }
if (wetness.ordinal() > 2) { if (wetness.ordinal() > 2) {
if (height > (WorldConstants.WORLD_SEA_LEVEL + WorldConstants.WORLD_MAX_HEIGHT) / 2) { if (height > (WORLD_SEA_LEVEL + WORLD_MAX_HEIGHT) / 2) {
return Biome.JUNGLE_HILLS; return Biome.JUNGLE_HILLS;
} else { } else {
return Biome.JUNGLE; return Biome.JUNGLE;
@@ -339,21 +340,20 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
@RequiredArgsConstructor @RequiredArgsConstructor
private class NoiseGenerator { private class NoiseGenerator {
int size = 256; int mask = WORLD_REGION_SIZE - 1;
int mask = size - 1; int[] perm = new int[WORLD_REGION_SIZE];
int[] perm = new int[size]; double[] gradsX = new double[WORLD_REGION_SIZE];
double[] gradsX = new double[size]; double[] gradsY = new double[WORLD_REGION_SIZE];
double[] gradsY = new double[size];
private final int seed; private final int seed;
void init() { void init() {
for (int i = 0; i < size; ++i) { for (int i = 0; i < WORLD_REGION_SIZE; ++i) {
int other = rand(i) % (i + 1); int other = rand(i) % (i + 1);
if (i > other) if (i > other)
perm[i] = perm[other]; perm[i] = perm[other];
perm[other] = i; perm[other] = i;
gradsX[i] = Math.cos(2.0f * Math.PI * i / size); gradsX[i] = Math.cos(2.0f * Math.PI * i / WORLD_REGION_SIZE);
gradsY[i] = Math.sin(2.0f * Math.PI * i / size); gradsY[i] = Math.sin(2.0f * Math.PI * i / WORLD_REGION_SIZE);
} }
} }
@@ -381,8 +381,8 @@ public class SeedBasedWorldGenerator implements WorldGenerator {
} }
int rand(int i) { int rand(int i) {
int x = (i * i) % 256; int x = (i * i) % WORLD_REGION_SIZE;
int y = (i + i * x) % 256; int y = (i + i * x) % WORLD_REGION_SIZE;
return (int) (Integer.MAX_VALUE * SeedRandomGenerator.random(x, y, seed)); return (int) (Integer.MAX_VALUE * SeedRandomGenerator.random(x, y, seed));
} }
} }

View File

@@ -9,6 +9,15 @@ public final class WorldConstants {
public static final int WORLD_MIN_HEIGHT = 28; public static final int WORLD_MIN_HEIGHT = 28;
public static final int WORLD_SEA_LEVEL = 64; public static final int WORLD_SEA_LEVEL = 64;
public static final int WORLD_MAX_HEIGHT = 128; public static final int WORLD_MAX_HEIGHT = 128;
public static final int WORLD_REGION_SIZE = 256;
public static final int WORLD_MAX_TEMPERATURE = 100;
public static final int WORLD_MAX_WETNESS = 100;
public static final double WORLD_LAND_SIZE = 53.0;
public static final double WORLD_LAKE_SIZE = 6.0;
public static final double WORLD_TEMPERATURE_SIZE = 41.0;
public static final double WORLD_TEMPERATURE_GRAD_SIZE = 2.99;
public static final int LANDFILL_GRASS_SURFACE_THIN = 5; public static final int LANDFILL_GRASS_SURFACE_THIN = 5;
public static final double WORLD_ROUGHNRESS = 0.35; public static final double WORLD_ROUGHNRESS = 0.35;