package game.worldgen; import java.util.List; import java.util.Set; import game.biome.Biome; import game.collect.Lists; import game.world.BlockPos; import game.world.LongHashMap; import game.worldgen.layer.GenLayer; import game.worldgen.layer.GenLayerAddAreas; import game.worldgen.layer.GenLayerAddExtra; import game.worldgen.layer.GenLayerAddSea; import game.worldgen.layer.GenLayerAddSnow; import game.worldgen.layer.GenLayerBase; import game.worldgen.layer.GenLayerBiome; import game.worldgen.layer.GenLayerBiomeEdge; import game.worldgen.layer.GenLayerEdge; import game.worldgen.layer.GenLayerFuzzyZoom; import game.worldgen.layer.GenLayerHills; import game.worldgen.layer.GenLayerRemoveEmpty; import game.worldgen.layer.GenLayerRiver; import game.worldgen.layer.GenLayerRiverInit; import game.worldgen.layer.GenLayerRiverMix; import game.worldgen.layer.GenLayerShore; import game.worldgen.layer.GenLayerSmooth; import game.worldgen.layer.GenLayerVoronoiZoom; import game.worldgen.layer.GenLayerZoom; import game.worldgen.layer.IntCache; public class BiomeGenLayered implements BiomeGenerator { private class CacheBlock { public final double[] factors = new double[256]; public final Biome[] biomes = new Biome[256]; public int xPosition; public int zPosition; public long lastAccessTime; public CacheBlock(int x, int z) { this.xPosition = x; this.zPosition = z; BiomeGenLayered.this.getFactors(this.factors, x << 4, z << 4, 16, 16); BiomeGenLayered.this.getBiomes(this.biomes, x << 4, z << 4, 16, 16, false); } public Biome getBiomeGenAt(int x, int z) { return this.biomes[x & 15 | (z & 15) << 4]; } } private final GenLayer genBiomes; private final GenLayer biomeIndexLayer; private final LongHashMap cacheMap = new LongHashMap(); private final List cache = Lists.newArrayList(); private long lastCleanupTime; // public BiomeGenNew(long seed, GeneratorSettings options) { // this(seed, options.biomeMode, options.fixedBiome, options.genMode == 2, options.biomeSize, // options.riverSize, options.snowRarity, options.seaRarity, options.shroomRarity, options.biomeRarity); // } // public BiomeGenLayered(Dimension dim, Random rand) { // this(); // } public BiomeGenLayered(long seed, Biome def, boolean fixed, int biomeSize, int riverSize, int snowRarity, int seaRarity, Biome[] add, int addRarity, Biome[] hot, Biome[] medium, Biome[] cold, Biome[] frost) { // GenLayer[] layers = GenLayer.getLayers(seed, fixedBiome, biomeSize, riverSize, snowRarity, seaRarity, shroomRarity, biomeRarity); GenLayer layer0t1 = new GenLayerBase(1L); layer0t1 = new GenLayerFuzzyZoom(2000L, layer0t1); GenLayerAddAreas layer2 = new GenLayerAddAreas(1L, layer0t1); GenLayerZoom layer3 = new GenLayerZoom(2001L, layer2); GenLayerAddAreas layer4t6 = new GenLayerAddAreas(2L, layer3); layer4t6 = new GenLayerAddAreas(50L, layer4t6); layer4t6 = new GenLayerAddAreas(70L, layer4t6); GenLayerRemoveEmpty layer7 = new GenLayerRemoveEmpty(2L, layer4t6); GenLayerAddSnow layer8 = new GenLayerAddSnow(2L, layer7, snowRarity); GenLayerAddAreas layer9 = new GenLayerAddAreas(3L, layer8); GenLayerEdge layer10t12 = new GenLayerEdge(2L, layer9, GenLayerEdge.Mode.COOL_WARM); layer10t12 = new GenLayerEdge(2L, layer10t12, GenLayerEdge.Mode.HEAT_ICE); // layer10t12 = new GenLayerEdge(3L, layer10t12, GenLayerEdge.Mode.SPECIAL); GenLayerZoom layer13t14 = new GenLayerZoom(2002L, layer10t12); layer13t14 = new GenLayerZoom(2003L, layer13t14); GenLayerAddAreas layer15 = new GenLayerAddAreas(4L, layer13t14); GenLayerAddExtra layer16 = new GenLayerAddExtra(5L, layer15, add, addRarity); GenLayerAddSea layer17 = new GenLayerAddSea(4L, layer16, seaRarity); GenLayer layer18 = GenLayerZoom.magnify(1000L, layer17, 0); GenLayer layer19 = GenLayerZoom.magnify(1000L, layer18, 0); GenLayerRiverInit layer20 = new GenLayerRiverInit(100L, layer19); GenLayerBiome layer21n = new GenLayerBiome(200L, layer18, hot, medium, cold, frost, def, fixed); GenLayer layer22n = GenLayerZoom.magnify(1000L, layer21n, 2); GenLayerBiomeEdge layer23n = new GenLayerBiomeEdge(1000L, layer22n); GenLayer layer21l = GenLayerZoom.magnify(1000L, layer20, 2); GenLayer layer24n = new GenLayerHills(1000L, layer23n, layer21l, def); GenLayer layer21t22a = GenLayerZoom.magnify(1000L, layer20, 2); layer21t22a = GenLayerZoom.magnify(1000L, layer21t22a, riverSize); GenLayerRiver layer23a = new GenLayerRiver(1L, layer21t22a); GenLayerSmooth layer24a = new GenLayerSmooth(1000L, layer23a); // layer24n = new GenLayerRareBiome(1001L, layer24n, biomeRarity); for(int k = 0; k < biomeSize; ++k) { layer24n = new GenLayerZoom((long)(1000 + k), layer24n); if(k == 0) { layer24n = new GenLayerAddAreas(3L, layer24n); } if(k == 1 || biomeSize == 1) { layer24n = new GenLayerShore(1000L, layer24n); } } GenLayerSmooth layer25n = new GenLayerSmooth(1000L, layer24n); GenLayerRiverMix layerOut = new GenLayerRiverMix(100L, layer25n, layer24a, def); GenLayer layerIndex = // perlinGen ? new GenLayerRiverMix(100L, layer25n, layer24a) : new GenLayerVoronoiZoom(10L, layerOut); layerOut.initWorldGenSeed(seed); layerIndex.initWorldGenSeed(seed); // return new GenLayer[] {layerOut, layerIndex}; this.genBiomes = layerOut; this.biomeIndexLayer = layerIndex; } private CacheBlock getBiomeCacheBlock(int x, int z) { x = x >> 4; z = z >> 4; long i = LongHashMap.packInt(x, z); // (long)x & 4294967295L | ((long)z & 4294967295L) << 32; CacheBlock blk = this.cacheMap.getValueByKey(i); if (blk == null) { blk = new CacheBlock(x, z); this.cacheMap.add(i, blk); this.cache.add(blk); } blk.lastAccessTime = System.currentTimeMillis(); return blk; } public void cleanupCache() { long i = System.currentTimeMillis(); long j = i - this.lastCleanupTime; if (j > 7500L || j < 0L) { this.lastCleanupTime = i; for (int k = 0; k < this.cache.size(); ++k) { CacheBlock blk = this.cache.get(k); long l = i - blk.lastAccessTime; if (l > 30000L || l < 0L) { this.cache.remove(k--); long i1 = LongHashMap.packInt(blk.xPosition, blk.zPosition) ; // (long)biomecache$block.xPosition & 4294967295L | ((long)biomecache$block.zPosition & 4294967295L) << 32; this.cacheMap.remove(i1); } } } } public Biome getBiomeGenerator(BlockPos pos, Biome def) { int x = pos.getX(); int z = pos.getZ(); Biome biome = this.getBiomeCacheBlock(x, z).getBiomeGenAt(x, z); return biome == null ? def : biome; } public void getFactors(double[] listToReuse, int x, int z, int width, int length) { IntCache.resetIntCache(); int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { Biome biome = Biome.getBiomeFromBiomeList(aint[i], Biome.DEF_BIOME); float f = biome.humidity * biome.temperature; if(f > 1.0F) f = 1.0F; listToReuse[i] = (double)f; } } public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ) { IntCache.resetIntCache(); if(true && sizeX == 16 && sizeZ == 16 && (xPos & 15) == 0 && (zPos & 15) == 0) { double[] cachedFacts = this.getBiomeCacheBlock(xPos, zPos).factors; System.arraycopy(cachedFacts, 0, factors, 0, sizeX * sizeZ); } else { int[] aint = this.biomeIndexLayer.getInts(xPos, zPos, sizeX, sizeZ); for(int i = 0; i < sizeX * sizeZ; ++i) { Biome biome = Biome.getBiomeFromBiomeList(aint[i], Biome.DEF_BIOME); float f = biome.humidity * biome.temperature; if(f > 1.0F) f = 1.0F; factors[i] = (double)f; } } } public void getGenBiomes(Biome[] biomes, int x, int z, int width, int height) { IntCache.resetIntCache(); int[] aint = this.genBiomes.getInts(x, z, width, height); for(int i = 0; i < width * height; ++i) { biomes[i] = Biome.getBiomeFromBiomeList(aint[i], Biome.DEF_BIOME); } } public void getChunkBiomes(Biome[] oldBiomeList, int x, int z, int width, int depth) { this.getBiomes(oldBiomeList, x, z, width, depth, true); } public void getBiomes(Biome[] listToReuse, int x, int z, int width, int length, boolean cache) { IntCache.resetIntCache(); if(cache && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0) { Biome[] biomes = this.getBiomeCacheBlock(x, z).biomes; System.arraycopy(biomes, 0, listToReuse, 0, width * length); } else { int[] aint = this.biomeIndexLayer.getInts(x, z, width, length); for(int i = 0; i < width * length; ++i) { listToReuse[i] = Biome.getBiomeFromBiomeList(aint[i], Biome.DEF_BIOME); } } } public boolean areBiomesViable(int x, int z, int size, Set allowed) { IntCache.resetIntCache(); int i = x - size >> 2; int j = z - size >> 2; int k = x + size >> 2; int l = z + size >> 2; int i1 = k - i + 1; int j1 = l - j + 1; int[] aint = this.genBiomes.getInts(i, j, i1, j1); for(int k1 = 0; k1 < i1 * j1; ++k1) { Biome biome = Biome.getBiome(aint[k1]); if(!allowed.contains(biome)) { return false; } } return true; } // public BlockPos findBiomePosition(int x, int z, int range, Set biomes, Random rand) { // IntCache.resetIntCache(); // int x1 = x - range >> 2; // int z1 = z - range >> 2; // int x2 = x + range >> 2; // int z2 = z + range >> 2; // int xs = x2 - x1 + 1; // int zs = z2 - z1 + 1; // int[] ints = this.genBiomes.getInts(x1, z1, xs, zs); // BlockPos pos = null; // int count = 0; // // for(int n = 0; n < xs * zs; ++n) { // int bx = x1 + n % xs << 2; // int bz = z1 + n / xs << 2; // Biome biome = Biome.getBiome(ints[n]); // // if(biomes.contains(biome) && (pos == null || rand.zrange(count + 1) == 0)) { // pos = new BlockPos(bx, 0, bz); // ++count; // } // } // // return pos; // } }