Biome generator
This commit is contained in:
parent
ce76ed9c7a
commit
8f08c310aa
14 changed files with 3173 additions and 44 deletions
|
@ -0,0 +1,62 @@
|
|||
package ru.betterend.world.generator;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryLookupCodec;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.source.BiomeSource;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.registry.BiomeRegistry;
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
|
||||
public class BetterEndBiomeSource extends BiomeSource {
|
||||
public static final Codec<BetterEndBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(RegistryLookupCodec.of(Registry.BIOME_KEY).forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.biomeRegistry;
|
||||
}), Codec.LONG.fieldOf("seed").stable().forGetter((theEndBiomeSource) -> {
|
||||
return theEndBiomeSource.seed;
|
||||
})).apply(instance, instance.stable(BetterEndBiomeSource::new));
|
||||
});
|
||||
private BiomeMap map;
|
||||
private final long seed;
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
|
||||
public BetterEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
|
||||
super(Collections.emptyList());
|
||||
this.seed = seed;
|
||||
this.map = new BiomeMap(seed, 50);
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
|
||||
BiomeRegistry.MUTABLE.clear();
|
||||
for (EndBiome biome : BiomePicker.getBiomes())
|
||||
BiomeRegistry.MUTABLE.put(biomeRegistry.getOrThrow(BiomeRegistry.getBiomeKey(biome)), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
|
||||
EndBiome netherBiome = map.getBiome(biomeX << 2, biomeZ << 2);
|
||||
if (biomeX == 0 && biomeZ == 0) {
|
||||
map.clearCache();
|
||||
}
|
||||
return biomeRegistry.getOrThrow(BiomeRegistry.getBiomeKey(netherBiome));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeSource withSeed(long seed) {
|
||||
return new BetterEndBiomeSource(biomeRegistry, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Codec<? extends BiomeSource> getCodec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
Registry.register(Registry.BIOME_SOURCE, new Identifier(BetterEnd.MOD_ID, "better_end_biome_source"), CODEC);
|
||||
}
|
||||
}
|
39
src/main/java/ru/betterend/world/generator/BiomeChunk.java
Normal file
39
src/main/java/ru/betterend/world/generator/BiomeChunk.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package ru.betterend.world.generator;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
|
||||
public class BiomeChunk
|
||||
{
|
||||
protected static final int WIDTH = 16;
|
||||
private static final int SM_WIDTH = WIDTH >> 1;
|
||||
private static final int MASK_A = SM_WIDTH - 1;
|
||||
private static final int MASK_C = WIDTH - 1;
|
||||
|
||||
private final EndBiome[][] biomes;
|
||||
|
||||
public BiomeChunk(BiomeMap map, Random random)
|
||||
{
|
||||
EndBiome[][] PreBio = new EndBiome[SM_WIDTH][SM_WIDTH];
|
||||
biomes = new EndBiome[WIDTH][WIDTH];
|
||||
|
||||
for (int x = 0; x < SM_WIDTH; x++)
|
||||
for (int z = 0; z < SM_WIDTH; z++)
|
||||
PreBio[x][z] = BiomePicker.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 EndBiome getBiome(int x, int z)
|
||||
{
|
||||
return biomes[x & MASK_C][z & MASK_C];
|
||||
}
|
||||
|
||||
private int offsetXZ(int x, Random random)
|
||||
{
|
||||
return ((x + random.nextInt(2)) >> 1) & MASK_A;
|
||||
}
|
||||
}
|
100
src/main/java/ru/betterend/world/generator/BiomeMap.java
Normal file
100
src/main/java/ru/betterend/world/generator/BiomeMap.java
Normal file
|
@ -0,0 +1,100 @@
|
|||
package ru.betterend.world.generator;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.gen.ChunkRandom;
|
||||
import ru.betterend.MHelper;
|
||||
import ru.betterend.noise.OpenSimplexNoise;
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
|
||||
public class BiomeMap
|
||||
{
|
||||
private static final HashMap<ChunkPos, BiomeChunk> MAPS = new HashMap<ChunkPos, BiomeChunk>();
|
||||
private static final ChunkRandom RANDOM = new ChunkRandom();
|
||||
|
||||
private final int size;
|
||||
private final int sizeXZ;
|
||||
private final int depth;
|
||||
private final OpenSimplexNoise noiseX;;
|
||||
private final OpenSimplexNoise noiseZ;
|
||||
|
||||
public BiomeMap(long seed, int size)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
public void clearCache()
|
||||
{
|
||||
if (MAPS.size() > 16)
|
||||
MAPS.clear();
|
||||
}
|
||||
|
||||
private EndBiome 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;
|
||||
}
|
||||
|
||||
ChunkPos cpos = new ChunkPos(MHelper.floor((double) x / BiomeChunk.WIDTH), MHelper.floor((double) z / BiomeChunk.WIDTH));
|
||||
BiomeChunk chunk = MAPS.get(cpos);
|
||||
if (chunk == null)
|
||||
{
|
||||
RANDOM.setTerrainSeed(cpos.x, cpos.z);
|
||||
chunk = new BiomeChunk(this, RANDOM);
|
||||
MAPS.put(cpos, chunk);
|
||||
}
|
||||
|
||||
return chunk.getBiome(MHelper.floor(x), MHelper.floor(z));
|
||||
}
|
||||
|
||||
public EndBiome getBiome(int x, int z)
|
||||
{
|
||||
EndBiome biome = getRawBiome(x, z);
|
||||
|
||||
if (biome.hasEdge() || (biome.hasParentBiome() && biome.getParentBiome().hasEdge()))
|
||||
{
|
||||
EndBiome 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;
|
||||
}
|
||||
}
|
30
src/main/java/ru/betterend/world/generator/BiomePicker.java
Normal file
30
src/main/java/ru/betterend/world/generator/BiomePicker.java
Normal file
|
@ -0,0 +1,30 @@
|
|||
package ru.betterend.world.generator;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import ru.betterend.world.biome.EndBiome;
|
||||
|
||||
public class BiomePicker {
|
||||
private static final List<EndBiome> BIOMES = Lists.newArrayList();
|
||||
private static float maxChance = 0;
|
||||
|
||||
public static void addBiome(EndBiome biome) {
|
||||
BIOMES.add(biome);
|
||||
maxChance = biome.setGenChance(maxChance);
|
||||
}
|
||||
|
||||
public static EndBiome getBiome(Random random) {
|
||||
float chance = random.nextFloat() * maxChance;
|
||||
for (EndBiome biome: BIOMES)
|
||||
if (biome.canGenerate(chance))
|
||||
return biome;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<EndBiome> getBiomes() {
|
||||
return BIOMES;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue