tcr/java/src/game/worldgen/BiomeGenLayered.java

277 lines
9.8 KiB
Java
Raw Normal View History

2025-03-11 00:23:54 +01:00
package game.worldgen;
import java.util.List;
import java.util.Set;
import game.biome.Biome;
2025-05-04 20:27:55 +02:00
import game.collect.Lists;
2025-03-11 00:23:54 +01:00
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) {
2025-04-14 12:35:45 +02:00
Biome biome = Biome.getBiome(aint[i], Biome.DEF_BIOME);
listToReuse[i] = (double)biome.getFactor();
2025-03-11 00:23:54 +01:00
}
}
public void genFactors(double[] factors, int xPos, int zPos, int sizeX, int sizeZ) {
IntCache.resetIntCache();
2025-04-14 12:35:45 +02:00
if(sizeX == 16 && sizeZ == 16 && (xPos & 15) == 0 && (zPos & 15) == 0) {
2025-03-11 00:23:54 +01:00
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) {
2025-04-14 12:35:45 +02:00
Biome biome = Biome.getBiome(aint[i], Biome.DEF_BIOME);
factors[i] = (double)biome.getFactor();
2025-03-11 00:23:54 +01:00
}
}
}
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) {
2025-04-14 12:35:45 +02:00
biomes[i] = Biome.getBiome(aint[i], Biome.DEF_BIOME);
2025-03-11 00:23:54 +01:00
}
}
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) {
2025-04-14 12:35:45 +02:00
listToReuse[i] = Biome.getBiome(aint[i], Biome.DEF_BIOME);
2025-03-11 00:23:54 +01:00
}
}
}
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;
// }
}