2025-03-11 00:23:54 +01:00
|
|
|
package game.worldgen;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Set;
|
|
|
|
|
2025-03-16 17:40:47 +01:00
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
2025-03-11 00:23:54 +01:00
|
|
|
import game.biome.Biome;
|
|
|
|
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<CacheBlock> cacheMap = new LongHashMap();
|
|
|
|
private final List<CacheBlock> cache = Lists.<CacheBlock>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<Biome> 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<Biome> 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;
|
|
|
|
// }
|
|
|
|
}
|