diff --git a/src/main/java/ru/betterend/world/generator/IslandLayer.java b/src/main/java/ru/betterend/world/generator/IslandLayer.java index beef77a8..644b4bf4 100644 --- a/src/main/java/ru/betterend/world/generator/IslandLayer.java +++ b/src/main/java/ru/betterend/world/generator/IslandLayer.java @@ -30,6 +30,8 @@ public class IslandLayer { private final int minY; private final int maxY; private final long center; + private int lastX = Integer.MIN_VALUE; + private int lastZ = Integer.MIN_VALUE; public IslandLayer(int seed, double distance, float scale, int center, int heightVariation) { this.distance = distance; @@ -48,22 +50,24 @@ public class IslandLayer { } public void updatePositions(double x, double z) { - positions.clear(); - int ix = MHelper.floor(x / distance); int iz = MHelper.floor(z / distance); - - for (int pox = -1; pox < 2; pox++) { - int px = pox + ix; - for (int poz = -1; poz < 2; poz++) { - int pz = poz + iz; - if (TerrainGenerator.noRingVoid() || (long) px + (long) pz > center) { - RANDOM.setSeed(getSeed(px, pz)); - double posX = (px + RANDOM.nextFloat()) * distance; - double posY = MHelper.randRange(minY, maxY, RANDOM); - double posZ = (pz + RANDOM.nextFloat()) * distance; - if (density.eval(posX * 0.01, posZ * 0.01) > 0) { - positions.add(new BlockPos(posX, posY, posZ)); + if (lastX != ix || lastZ != iz) { + lastX = ix; + lastZ = iz; + positions.clear(); + for (int pox = -1; pox < 2; pox++) { + int px = pox + ix; + for (int poz = -1; poz < 2; poz++) { + int pz = poz + iz; + if (TerrainGenerator.noRingVoid() || (long) px + (long) pz > center) { + RANDOM.setSeed(getSeed(px, pz)); + double posX = (px + RANDOM.nextFloat()) * distance; + double posY = MHelper.randRange(minY, maxY, RANDOM); + double posZ = (pz + RANDOM.nextFloat()) * distance; + if (density.eval(posX * 0.01, posZ * 0.01) > 0) { + positions.add(new BlockPos(posX, posY, posZ)); + } } } } @@ -102,7 +106,7 @@ public class IslandLayer { } public void clearCache() { - if (islands.size() > 32) { + if (islands.size() > 128) { islands.clear(); } } diff --git a/src/main/java/ru/betterend/world/generator/TerrainGenerator.java b/src/main/java/ru/betterend/world/generator/TerrainGenerator.java index 4f8c8e9a..8f19e421 100644 --- a/src/main/java/ru/betterend/world/generator/TerrainGenerator.java +++ b/src/main/java/ru/betterend/world/generator/TerrainGenerator.java @@ -3,6 +3,7 @@ package ru.betterend.world.generator; import java.util.Random; import java.util.concurrent.locks.ReentrantLock; +import net.minecraft.util.math.MathHelper; import ru.betterend.config.Configs; import ru.betterend.noise.OpenSimplexNoise; import ru.betterend.util.MHelper; @@ -118,4 +119,46 @@ public class TerrainGenerator { LOCKER.unlock(); return false; } + + /** + * Check if this is land + * @param x - biome pos x + * @param z - biome pos z + */ + public static int getHeight(int x, int z) { + LOCKER.lock(); + + //x >>= 3; + //z >>= 3; + double px = (double) x / 8.0; + double pz = (double) z / 8.0; + + double distortion1 = noise1.eval(px * 0.1, pz * 0.1) * 20 + noise2.eval(px * 0.2, pz * 0.2) * 10 + noise1.eval(px * 0.4, pz * 0.4) * 5; + double distortion2 = noise2.eval(px * 0.1, pz * 0.1) * 20 + noise1.eval(px * 0.2, pz * 0.2) * 10 + noise2.eval(px * 0.4, pz * 0.4) * 5; + px = (double) x * SCALE_XZ + distortion1; + pz = (double) z * SCALE_XZ + distortion2; + + largeIslands.updatePositions(px, pz); + mediumIslands.updatePositions(px, pz); + smallIslands.updatePositions(px, pz); + + for (int y = 32; y >= 0; y--) { + double py = (double) y * SCALE_Y; + float dist = largeIslands.getDensity(px, py, pz); + dist = dist > 1 ? dist : MHelper.max(dist, mediumIslands.getDensity(px, py, pz)); + dist = dist > 1 ? dist : MHelper.max(dist, smallIslands.getDensity(px, py, pz)); + if (dist > -0.5F) { + dist += noise1.eval(px * 0.01, py * 0.01, pz * 0.01) * 0.04; + dist += noise2.eval(px * 0.05, py * 0.05, pz * 0.05) * 0.02; + dist += noise1.eval(px * 0.1, py * 0.1, pz * 0.1) * 0.01; + } + if (dist > 0) { + LOCKER.unlock(); + return MathHelper.floor(MathHelper.clamp(y + dist, y, y + 1) * SCALE_Y); + } + } + + LOCKER.unlock(); + return 0; + } } diff --git a/src/main/java/ru/betterend/world/structures/features/StructureMountain.java b/src/main/java/ru/betterend/world/structures/features/StructureMountain.java index 8de38254..6f84c53a 100644 --- a/src/main/java/ru/betterend/world/structures/features/StructureMountain.java +++ b/src/main/java/ru/betterend/world/structures/features/StructureMountain.java @@ -29,7 +29,7 @@ public class StructureMountain extends StructureFeatureBase { int x = (chunkX << 4) | MHelper.randRange(4, 12, random); int z = (chunkZ << 4) | MHelper.randRange(4, 12, random); int y = chunkGenerator.getHeight(x, z, Type.WORLD_SURFACE_WG); - if (y > 50) { + if (y > 5) { float radius = MHelper.randRange(50, 100, random); float height = radius * MHelper.randRange(0.8F, 1.2F, random); MountainPiece piece = new MountainPiece(new BlockPos(x, y, z), radius, height, random, biome); diff --git a/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java b/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java index 73958f31..cd875fcc 100644 --- a/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java +++ b/src/main/java/ru/betterend/world/structures/piece/MountainPiece.java @@ -118,15 +118,15 @@ public class MountainPiece extends BasePiece { } minY = pos.getY(); minY = Math.max(minY, map2.get(x, z)); - if (minY > 10) { - float maxY = dist * height * getHeightClamp(world, 8, px, pz); + if (minY > center.getY() - 8) { + float maxY = dist * height * getHeightClamp(world, 12, px, pz); if (maxY > 0) { maxY *= (float) noise1.eval(px * 0.05, pz * 0.05) * 0.3F + 0.7F; maxY *= (float) noise1.eval(px * 0.1, pz * 0.1) * 0.1F + 0.8F; - maxY += 56; + maxY += center.getY(); int maxYI = (int) (maxY); int cover = maxYI - 1; - boolean needCover = (noise1.eval(px * 0.1, pz * 0.1) + MHelper.randRange(-0.4, 0.4, random) - (maxY - 70) * 0.1) > 0; + boolean needCover = (noise1.eval(px * 0.1, pz * 0.1) + MHelper.randRange(-0.4, 0.4, random) - (center.getY() + 14) * 0.1) > 0; for (int y = minY - 1; y < maxYI; y++) { pos.setY(y); chunk.setBlockState(pos, needCover && y == cover ? top : Blocks.END_STONE.getDefaultState(), false); @@ -140,7 +140,7 @@ public class MountainPiece extends BasePiece { map = chunk.getHeightmap(Type.WORLD_SURFACE); // Big crystals - int count = (map.get(8, 8) - 80) / 7; + int count = (map.get(8, 8) - (center.getY() + 24)) / 7; count = MathHelper.clamp(count, 0, 8); for (int i = 0; i < count; i++) { int radius = MHelper.randRange(2, 3, random); @@ -158,7 +158,7 @@ public class MountainPiece extends BasePiece { } // Small crystals - count = (map.get(8, 8) - 80) / 2; + count = (map.get(8, 8) - (center.getY() + 24)) / 2; count = MathHelper.clamp(count, 4, 8); for (int i = 0; i < count; i++) { int radius = MHelper.randRange(1, 2, random); @@ -190,10 +190,13 @@ public class MountainPiece extends BasePiece { return -10; } h = world.getTopY(Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); - if (h < 57) { - heightmap.put(p, -4); - return -4; + h = MathHelper.abs(h - center.getY()); + if (h > 4) { + h = 4 - h; + heightmap.put(p, h); + return h; } + h = MHelper.floor(noise2.eval(pos.getX() * 0.01, pos.getZ() * 0.01) * noise2.eval(pos.getX() * 0.002, pos.getZ() * 0.002) * 8 + 8); if (h < 0) {