Biome API (WIP), javadocs, biome map
This commit is contained in:
parent
c89235ec92
commit
67c9c2302d
9 changed files with 424 additions and 38 deletions
35
src/main/java/ru/bclib/world/generator/BiomeChunk.java
Normal file
35
src/main/java/ru/bclib/world/generator/BiomeChunk.java
Normal file
|
@ -0,0 +1,35 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
public class BiomeChunk {
|
||||
protected static final int WIDTH = 16;
|
||||
private static final int SM_WIDTH = WIDTH >> 1;
|
||||
private static final int MASK_OFFSET = SM_WIDTH - 1;
|
||||
protected static final int MASK_WIDTH = WIDTH - 1;
|
||||
|
||||
private final BCLBiome[][] biomes;
|
||||
|
||||
public BiomeChunk(BiomeMap map, Random random, BiomePicker picker) {
|
||||
BCLBiome[][] PreBio = new BCLBiome[SM_WIDTH][SM_WIDTH];
|
||||
biomes = new BCLBiome[WIDTH][WIDTH];
|
||||
|
||||
for (int x = 0; x < SM_WIDTH; x++)
|
||||
for (int z = 0; z < SM_WIDTH; z++)
|
||||
PreBio[x][z] = picker.getBiome(random);
|
||||
|
||||
for (int x = 0; x < WIDTH; x++)
|
||||
for (int z = 0; z < WIDTH; z++)
|
||||
biomes[x][z] = PreBio[offsetXZ(x, random)][offsetXZ(z, random)].getSubBiome(random);
|
||||
}
|
||||
|
||||
public BCLBiome getBiome(int x, int z) {
|
||||
return biomes[x & MASK_WIDTH][z & MASK_WIDTH];
|
||||
}
|
||||
|
||||
private int offsetXZ(int x, Random random) {
|
||||
return ((x + random.nextInt(2)) >> 1) & MASK_OFFSET;
|
||||
}
|
||||
}
|
113
src/main/java/ru/bclib/world/generator/BiomeMap.java
Normal file
113
src/main/java/ru/bclib/world/generator/BiomeMap.java
Normal file
|
@ -0,0 +1,113 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import ru.bclib.noise.OpenSimplexNoise;
|
||||
import ru.bclib.util.MHelper;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
public class BiomeMap {
|
||||
private static final WorldgenRandom RANDOM = new WorldgenRandom();
|
||||
|
||||
private final Map<ChunkPos, BiomeChunk> maps = Maps.newHashMap();
|
||||
private final int size;
|
||||
private final int sizeXZ;
|
||||
private final int depth;
|
||||
private final OpenSimplexNoise noiseX;
|
||||
private final OpenSimplexNoise noiseZ;
|
||||
private final BiomePicker picker;
|
||||
private final long seed;
|
||||
|
||||
public BiomeMap(long seed, int size, BiomePicker picker) {
|
||||
maps.clear();
|
||||
RANDOM.setSeed(seed);
|
||||
noiseX = new OpenSimplexNoise(RANDOM.nextLong());
|
||||
noiseZ = new OpenSimplexNoise(RANDOM.nextLong());
|
||||
this.sizeXZ = size;
|
||||
depth = (int) Math.ceil(Math.log(size) / Math.log(2)) - 2;
|
||||
this.size = 1 << depth;
|
||||
this.picker = picker;
|
||||
this.seed = seed;
|
||||
}
|
||||
|
||||
public long getSeed() {
|
||||
return seed;
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
if (maps.size() > 32) {
|
||||
maps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private BCLBiome getRawBiome(int bx, int bz) {
|
||||
double x = (double) bx * size / sizeXZ;
|
||||
double z = (double) bz * size / sizeXZ;
|
||||
double nx = x;
|
||||
double nz = z;
|
||||
|
||||
double px = bx * 0.2;
|
||||
double pz = bz * 0.2;
|
||||
|
||||
for (int i = 0; i < depth; i++) {
|
||||
nx = (x + noiseX.eval(px, pz)) / 2F;
|
||||
nz = (z + noiseZ.eval(px, pz)) / 2F;
|
||||
|
||||
x = nx;
|
||||
z = nz;
|
||||
|
||||
px = px / 2 + i;
|
||||
pz = pz / 2 + i;
|
||||
}
|
||||
|
||||
bx = MHelper.floor(x);
|
||||
bz = MHelper.floor(z);
|
||||
if ((bx & BiomeChunk.MASK_WIDTH) == BiomeChunk.MASK_WIDTH) {
|
||||
x += (bz / 2) & 1;
|
||||
}
|
||||
if ((bz & BiomeChunk.MASK_WIDTH) == BiomeChunk.MASK_WIDTH) {
|
||||
z += (bx / 2) & 1;
|
||||
}
|
||||
|
||||
ChunkPos cpos = new ChunkPos(MHelper.floor(x / BiomeChunk.WIDTH), MHelper.floor(z / BiomeChunk.WIDTH));
|
||||
BiomeChunk chunk = maps.get(cpos);
|
||||
if (chunk == null) {
|
||||
RANDOM.setBaseChunkSeed(cpos.x, cpos.z);
|
||||
chunk = new BiomeChunk(this, RANDOM, picker);
|
||||
maps.put(cpos, chunk);
|
||||
}
|
||||
|
||||
return chunk.getBiome(MHelper.floor(x), MHelper.floor(z));
|
||||
}
|
||||
|
||||
public BCLBiome getBiome(int x, int z) {
|
||||
BCLBiome biome = getRawBiome(x, z);
|
||||
|
||||
if (biome.hasEdge() || (biome.hasParentBiome() && biome.getParentBiome().hasEdge())) {
|
||||
BCLBiome search = biome;
|
||||
if (biome.hasParentBiome()) {
|
||||
search = biome.getParentBiome();
|
||||
}
|
||||
int d = (int) Math.ceil(search.getEdgeSize() / 4F) << 2;
|
||||
|
||||
boolean edge = !search.isSame(getRawBiome(x + d, z));
|
||||
edge = edge || !search.isSame(getRawBiome(x - d, z));
|
||||
edge = edge || !search.isSame(getRawBiome(x, z + d));
|
||||
edge = edge || !search.isSame(getRawBiome(x, z - d));
|
||||
edge = edge || !search.isSame(getRawBiome(x - 1, z - 1));
|
||||
edge = edge || !search.isSame(getRawBiome(x - 1, z + 1));
|
||||
edge = edge || !search.isSame(getRawBiome(x + 1, z - 1));
|
||||
edge = edge || !search.isSame(getRawBiome(x + 1, z + 1));
|
||||
|
||||
if (edge) {
|
||||
biome = search.getEdge();
|
||||
}
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
}
|
69
src/main/java/ru/bclib/world/generator/BiomePicker.java
Normal file
69
src/main/java/ru/bclib/world/generator/BiomePicker.java
Normal file
|
@ -0,0 +1,69 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import ru.bclib.util.WeighTree;
|
||||
import ru.bclib.util.WeightedList;
|
||||
import ru.bclib.world.biomes.BCLBiome;
|
||||
|
||||
public class BiomePicker {
|
||||
private final Set<ResourceLocation> immutableIDs = Sets.newHashSet();
|
||||
private final List<BCLBiome> biomes = Lists.newArrayList();
|
||||
private int biomeCount = 0;
|
||||
private WeighTree<BCLBiome> tree;
|
||||
|
||||
public void addBiome(BCLBiome biome) {
|
||||
immutableIDs.add(biome.getID());
|
||||
biomes.add(biome);
|
||||
biomeCount ++;
|
||||
}
|
||||
|
||||
public void addBiomeMutable(BCLBiome biome) {
|
||||
biomes.add(biome);
|
||||
}
|
||||
|
||||
public void clearMutables() {
|
||||
for (int i = biomes.size() - 1; i >= biomeCount; i--) {
|
||||
biomes.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
public BCLBiome getBiome(Random random) {
|
||||
return biomes.isEmpty() ? null : tree.get(random);
|
||||
}
|
||||
|
||||
public List<BCLBiome> getBiomes() {
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public boolean containsImmutable(ResourceLocation id) {
|
||||
return immutableIDs.contains(id);
|
||||
}
|
||||
|
||||
public void removeMutableBiome(ResourceLocation id) {
|
||||
for (int i = biomeCount; i < biomes.size(); i++) {
|
||||
BCLBiome biome = biomes.get(i);
|
||||
if (biome.getID().equals(id)) {
|
||||
biomes.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rebuild() {
|
||||
if (biomes.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
WeightedList<BCLBiome> list = new WeightedList<BCLBiome>();
|
||||
biomes.forEach((biome) -> {
|
||||
list.add(biome, biome.getGenChance());
|
||||
});
|
||||
tree = new WeighTree<BCLBiome>(list);
|
||||
}
|
||||
}
|
6
src/main/java/ru/bclib/world/generator/BiomeType.java
Normal file
6
src/main/java/ru/bclib/world/generator/BiomeType.java
Normal file
|
@ -0,0 +1,6 @@
|
|||
package ru.bclib.world.generator;
|
||||
|
||||
public enum BiomeType {
|
||||
LAND,
|
||||
VOID;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue