Re-Added seed in serialization

This commit is contained in:
Frank 2022-05-13 20:52:02 +02:00
parent dc7a875679
commit 38b8883b6a
3 changed files with 382 additions and 342 deletions

View file

@ -19,13 +19,14 @@ public abstract class BCLBiomeSource extends BiomeSource {
protected BCLBiomeSource(Registry<Biome> biomeRegistry, List<Holder<Biome>> list) { protected BCLBiomeSource(Registry<Biome> biomeRegistry, List<Holder<Biome>> list) {
super(preInit(biomeRegistry, list)); super(preInit(biomeRegistry, list));
System.out.println(this + " with Registry: "+biomeRegistry);
this.biomeRegistry = biomeRegistry; this.biomeRegistry = biomeRegistry;
BiomeAPI.initRegistry(biomeRegistry); BiomeAPI.initRegistry(biomeRegistry);
} }
public void setSeed(long seed){ public void setSeed(long seed){
System.out.println(this+" set Seed: " + seed);
this.currentSeed = seed; this.currentSeed = seed;
} }
} }

View file

@ -1,7 +1,5 @@
package ru.bclib.world.generator; package ru.bclib.world.generator;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
@ -15,6 +13,9 @@ import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.levelgen.LegacyRandomSource; import net.minecraft.world.level.levelgen.LegacyRandomSource;
import net.minecraft.world.level.levelgen.WorldgenRandom; import net.minecraft.world.level.levelgen.WorldgenRandom;
import net.minecraft.world.level.levelgen.synth.SimplexNoise; import net.minecraft.world.level.levelgen.synth.SimplexNoise;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import ru.bclib.BCLib; import ru.bclib.BCLib;
import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.api.biomes.BiomeAPI;
import ru.bclib.config.ConfigKeeper.StringArrayEntry; import ru.bclib.config.ConfigKeeper.StringArrayEntry;
@ -25,204 +26,231 @@ import ru.bclib.world.biomes.BCLBiome;
import ru.bclib.world.generator.map.hex.HexBiomeMap; import ru.bclib.world.generator.map.hex.HexBiomeMap;
import ru.bclib.world.generator.map.square.SquareBiomeMap; import ru.bclib.world.generator.map.square.SquareBiomeMap;
import java.awt.Point; import java.awt.*;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
public class BCLibEndBiomeSource extends BCLBiomeSource { public class BCLibEndBiomeSource extends BCLBiomeSource {
public static Codec<BCLibEndBiomeSource> CODEC = RecordCodecBuilder.create((instance) -> instance.group(RegistryOps.retrieveRegistry(Registry.BIOME_REGISTRY).forGetter((theEndBiomeSource) -> null)).apply(instance, instance.stable(BCLibEndBiomeSource::new))); private static final OpenSimplexNoise SMALL_NOISE = new OpenSimplexNoise(8324);
private static final OpenSimplexNoise SMALL_NOISE = new OpenSimplexNoise(8324); public static Codec<BCLibEndBiomeSource> CODEC
private Function<Point, Boolean> endLandFunction; = RecordCodecBuilder.create((instance) -> instance.group(
RegistryOps
private SimplexNoise noise; .retrieveRegistry(Registry.BIOME_REGISTRY)
private final Holder<Biome> centerBiome; .forGetter((theEndBiomeSource) -> theEndBiomeSource.biomeRegistry),
private final Holder<Biome> barrens; Codec
private BiomeMap mapLand; .LONG
private BiomeMap mapVoid; .fieldOf("seed")
private final Point pos; .stable()
.forGetter(source -> source.currentSeed))
public BCLibEndBiomeSource(Registry<Biome> biomeRegistry) { .apply(instance,
super(biomeRegistry, getBiomes(biomeRegistry)); instance.stable(BCLibEndBiomeSource::new)
)
BiomeAPI.END_LAND_BIOME_PICKER.clearMutables(); );
BiomeAPI.END_VOID_BIOME_PICKER.clearMutables(); private final Holder<Biome> centerBiome;
private final Holder<Biome> barrens;
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include", "end_void_biomes", StringArrayEntry.class).getValue(); private final Point pos;
this.possibleBiomes().forEach(biome -> { private Function<Point, Boolean> endLandFunction;
ResourceLocation key = biome.unwrapKey().orElseThrow().location(); private SimplexNoise noise;
String group = key.getNamespace() + "." + key.getPath(); private BiomeMap mapLand;
private BiomeMap mapVoid;
if (!BiomeAPI.hasBiome(key)) {
BCLBiome bclBiome = new BCLBiome(key, biome.value());
if (includeVoid.contains(key.toString())) {
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
}
else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
}
}
else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) && !BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(key)) {
if (includeVoid.contains(key.toString())) {
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
}
else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
}
}
}
}
}
});
BiomeAPI.END_LAND_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_VOID_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_LAND_BIOME_PICKER.rebuild();
BiomeAPI.END_VOID_BIOME_PICKER.rebuild();
this.centerBiome = biomeRegistry.getOrCreateHolder(Biomes.THE_END);
this.barrens = biomeRegistry.getOrCreateHolder(Biomes.END_BARRENS);
this.endLandFunction = GeneratorOptions.getEndLandFunction();
this.pos = new Point();
}
private void initMap(long seed){
if (GeneratorOptions.useOldBiomeGenerator()) {
this.mapLand = new SquareBiomeMap(seed, GeneratorOptions.getBiomeSizeEndLand(), BiomeAPI.END_LAND_BIOME_PICKER);
this.mapVoid = new SquareBiomeMap(seed, GeneratorOptions.getBiomeSizeEndVoid(), BiomeAPI.END_VOID_BIOME_PICKER);
}
else {
this.mapLand = new HexBiomeMap(seed, GeneratorOptions.getBiomeSizeEndLand(), BiomeAPI.END_LAND_BIOME_PICKER);
this.mapVoid = new HexBiomeMap(seed, GeneratorOptions.getBiomeSizeEndVoid(), BiomeAPI.END_VOID_BIOME_PICKER);
}
WorldgenRandom chunkRandom = new WorldgenRandom(new LegacyRandomSource(seed));
chunkRandom.consumeCount(17292);
this.noise = new SimplexNoise(chunkRandom);
}
@Override
public void setSeed(long seed) {
super.setSeed(seed);
initMap(seed);
}
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
List<String> includeLand = Configs.BIOMES_CONFIG.getEntry("force_include", "end_land_biomes", StringArrayEntry.class).getValue();
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include", "end_void_biomes", StringArrayEntry.class).getValue();
return biomeRegistry.stream()
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
.filter(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (includeLand.contains(key.toString()) || includeVoid.contains(key.toString())) { public BCLibEndBiomeSource(Registry<Biome> biomeRegistry, long seed) {
return true; this(biomeRegistry);
} this.setSeed(seed);
}
final boolean isEndBiome = biome.is(BiomeTags.IS_END); public BCLibEndBiomeSource(Registry<Biome> biomeRegistry) {
if (GeneratorOptions.addEndBiomesByTag() && isEndBiome) { super(biomeRegistry, getBiomes(biomeRegistry));
return true;
}
BCLBiome bclBiome = BiomeAPI.getBiome(key); BiomeAPI.END_LAND_BIOME_PICKER.clearMutables();
if (bclBiome != BiomeAPI.EMPTY_BIOME) { BiomeAPI.END_VOID_BIOME_PICKER.clearMutables();
if (bclBiome.getParentBiome() != null) {
bclBiome = bclBiome.getParentBiome();
}
key = bclBiome.getID();
}
return BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) || BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(key) || (isEndBiome && BiomeAPI.isDatapackBiome(key));
}).toList();
}
@Override
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
if (mapLand==null || mapVoid==null)
return this.possibleBiomes().stream().findFirst().get();
long posX = biomeX << 2;
long posZ = biomeZ << 2;
long farEndBiomes = GeneratorOptions.getFarEndBiomes();
long dist = posX * posX + posZ * posZ;
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
mapLand.clearCache();
mapVoid.clearCache();
}
if (endLandFunction == null) {
if (dist <= farEndBiomes) return centerBiome;
float height = getLegacyHeightValue(
noise,
(biomeX >> 1) + 1,
(biomeZ >> 1) + 1
) + (float) SMALL_NOISE.eval(biomeX, biomeZ) * 5;
if (height > -20F && height < -5F) {
return barrens;
}
if (height < -10F) {
return mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
else {
return mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
}
else {
pos.setLocation(biomeX, biomeZ);
if (endLandFunction.apply(pos)) {
return dist <= farEndBiomes ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
else {
return dist <= farEndBiomes ? barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
}
}
public static float getLegacyHeightValue(SimplexNoise simplexNoise, int i, int j) {
int k = i / 2;
int l = j / 2;
int m = i % 2;
int n = j % 2;
float f = 100.0f - Mth.sqrt(i * i + j * j) * 8.0f;
f = Mth.clamp(f, -100.0f, 80.0f);
for (int o = -12; o <= 12; ++o) {
for (int p = -12; p <= 12; ++p) {
long q = k + o;
long r = l + p;
if (q * q + r * r <= 4096L || !(simplexNoise.getValue(q, r) < (double)-0.9f)) continue;
float g = (Mth.abs(q) * 3439.0f + Mth.abs(r) * 147.0f) % 13.0f + 9.0f;
float h = m - o * 2;
float s = n - p * 2;
float t = 100.0f - Mth.sqrt(h * h + s * s) * g;
t = Mth.clamp(t, -100.0f, 80.0f);
f = Math.max(f, t);
}
}
return f;
}
@Override List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include",
protected Codec<? extends BiomeSource> codec() { "end_void_biomes",
return CODEC; StringArrayEntry.class).getValue();
} this.possibleBiomes().forEach(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
public static void register() { String group = key.getNamespace() + "." + key.getPath();
Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC);
} if (!BiomeAPI.hasBiome(key)) {
BCLBiome bclBiome = new BCLBiome(key, biome.value());
@Override
public String toString() { if (includeVoid.contains(key.toString())) {
return "BCLib - The End BiomeSource"; BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
} } else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
}
} else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) && !BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(
key)) {
if (includeVoid.contains(key.toString())) {
BiomeAPI.END_VOID_BIOME_PICKER.addBiomeMutable(bclBiome);
} else {
BiomeAPI.END_LAND_BIOME_PICKER.addBiomeMutable(bclBiome);
}
}
}
}
}
});
BiomeAPI.END_LAND_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_VOID_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.END_LAND_BIOME_PICKER.rebuild();
BiomeAPI.END_VOID_BIOME_PICKER.rebuild();
this.centerBiome = biomeRegistry.getOrCreateHolder(Biomes.THE_END);
this.barrens = biomeRegistry.getOrCreateHolder(Biomes.END_BARRENS);
this.endLandFunction = GeneratorOptions.getEndLandFunction();
this.pos = new Point();
}
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
List<String> includeLand = Configs.BIOMES_CONFIG.getEntry("force_include",
"end_land_biomes",
StringArrayEntry.class).getValue();
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry("force_include",
"end_void_biomes",
StringArrayEntry.class).getValue();
return biomeRegistry.stream()
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
.filter(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (includeLand.contains(key.toString()) || includeVoid.contains(key.toString())) {
return true;
}
final boolean isEndBiome = biome.is(BiomeTags.IS_END);
if (GeneratorOptions.addEndBiomesByTag() && isEndBiome) {
return true;
}
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() != null) {
bclBiome = bclBiome.getParentBiome();
}
key = bclBiome.getID();
}
return BiomeAPI.END_LAND_BIOME_PICKER.containsImmutable(key) || BiomeAPI.END_VOID_BIOME_PICKER.containsImmutable(
key) || (isEndBiome && BiomeAPI.isDatapackBiome(key));
}).toList();
}
public static float getLegacyHeightValue(SimplexNoise simplexNoise, int i, int j) {
int k = i / 2;
int l = j / 2;
int m = i % 2;
int n = j % 2;
float f = 100.0f - Mth.sqrt(i * i + j * j) * 8.0f;
f = Mth.clamp(f, -100.0f, 80.0f);
for (int o = -12; o <= 12; ++o) {
for (int p = -12; p <= 12; ++p) {
long q = k + o;
long r = l + p;
if (q * q + r * r <= 4096L || !(simplexNoise.getValue(q, r) < (double) -0.9f)) continue;
float g = (Mth.abs(q) * 3439.0f + Mth.abs(r) * 147.0f) % 13.0f + 9.0f;
float h = m - o * 2;
float s = n - p * 2;
float t = 100.0f - Mth.sqrt(h * h + s * s) * g;
t = Mth.clamp(t, -100.0f, 80.0f);
f = Math.max(f, t);
}
}
return f;
}
public static void register() {
Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC);
}
private void initMap(long seed) {
if (GeneratorOptions.useOldBiomeGenerator()) {
this.mapLand = new SquareBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndLand(),
BiomeAPI.END_LAND_BIOME_PICKER);
this.mapVoid = new SquareBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndVoid(),
BiomeAPI.END_VOID_BIOME_PICKER);
} else {
this.mapLand = new HexBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndLand(),
BiomeAPI.END_LAND_BIOME_PICKER);
this.mapVoid = new HexBiomeMap(seed,
GeneratorOptions.getBiomeSizeEndVoid(),
BiomeAPI.END_VOID_BIOME_PICKER);
}
WorldgenRandom chunkRandom = new WorldgenRandom(new LegacyRandomSource(seed));
chunkRandom.consumeCount(17292);
this.noise = new SimplexNoise(chunkRandom);
}
@Override
public void setSeed(long seed) {
super.setSeed(seed);
initMap(seed);
}
@Override
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler sampler) {
if (mapLand == null || mapVoid == null)
return this.possibleBiomes().stream().findFirst().get();
long posX = biomeX << 2;
long posZ = biomeZ << 2;
long farEndBiomes = GeneratorOptions.getFarEndBiomes();
long dist = posX * posX + posZ * posZ;
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
mapLand.clearCache();
mapVoid.clearCache();
}
if (endLandFunction == null) {
if (dist <= farEndBiomes) return centerBiome;
float height = getLegacyHeightValue(
noise,
(biomeX >> 1) + 1,
(biomeZ >> 1) + 1
) + (float) SMALL_NOISE.eval(biomeX, biomeZ) * 5;
if (height > -20F && height < -5F) {
return barrens;
}
if (height < -10F) {
return mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
} else {
return mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
} else {
pos.setLocation(biomeX, biomeZ);
if (endLandFunction.apply(pos)) {
return dist <= farEndBiomes ? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).getActualBiome();
} else {
return dist <= farEndBiomes ? barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).getActualBiome();
}
}
}
@Override
protected Codec<? extends BiomeSource> codec() {
return CODEC;
}
@Override
public String toString() {
return "BCLib - The End BiomeSource";
}
} }

View file

@ -1,18 +1,19 @@
package ru.bclib.world.generator; package ru.bclib.world.generator;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.core.DefaultedRegistry;
import net.minecraft.core.Holder; import net.minecraft.core.Holder;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.Registry; import net.minecraft.core.Registry;
import net.minecraft.data.BuiltinRegistries;
import net.minecraft.resources.RegistryOps; import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.BiomeTags; import net.minecraft.tags.BiomeTags;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.level.biome.*; import net.minecraft.world.level.biome.*;
import com.mojang.datafixers.kinds.Applicative;
import com.mojang.datafixers.util.Either;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import org.apache.commons.lang3.function.TriFunction; import org.apache.commons.lang3.function.TriFunction;
import ru.bclib.BCLib; import ru.bclib.BCLib;
import ru.bclib.api.biomes.BiomeAPI; import ru.bclib.api.biomes.BiomeAPI;
@ -25,160 +26,170 @@ import ru.bclib.world.generator.map.hex.HexBiomeMap;
import ru.bclib.world.generator.map.square.SquareBiomeMap; import ru.bclib.world.generator.map.square.SquareBiomeMap;
import java.util.List; import java.util.List;
import java.util.function.Function;
public class BCLibNetherBiomeSource extends BCLBiomeSource { public class BCLibNetherBiomeSource extends BCLBiomeSource {
private static boolean forceLegacyGenerator = false;
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder private static int lastWorldHeight;
.create(instance -> instance private static int worldHeight;
.group(RegistryOps public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder
.retrieveRegistry(Registry.BIOME_REGISTRY) .create(instance -> instance
.forGetter(source -> source.biomeRegistry) .group(RegistryOps
.retrieveRegistry(Registry.BIOME_REGISTRY)
) .forGetter(source -> source.biomeRegistry),
.apply(instance, instance.stable(BCLibNetherBiomeSource::new)) Codec
); .LONG
.fieldOf("seed")
private BiomeMap biomeMap; .stable()
.forGetter(source -> {
private static boolean forceLegacyGenerator = false; return source.currentSeed;
private static int lastWorldHeight; })
private static int worldHeight; )
.apply(instance, instance.stable(BCLibNetherBiomeSource::new))
/** );
* When true, the older square generator is used for the nether. private BiomeMap biomeMap;
*
* This override is used (for example) by BetterNether to force the legacy generation for worlds
* that were created before 1.18
* @param val wether or not you want to force the old generatore.
*/
public static void setForceLegacyGeneration(boolean val){
forceLegacyGenerator = val;
}
/**
* Set world height, used when Nether is larger than vanilla 128 blocks tall.
* @param worldHeight height of the Nether ceiling.
*/
public static void setWorldHeight(int worldHeight) {
BCLibNetherBiomeSource.worldHeight = worldHeight;
}
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry) { public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry) {
super(biomeRegistry, getBiomes(biomeRegistry)); super(biomeRegistry, getBiomes(biomeRegistry));
BiomeAPI.NETHER_BIOME_PICKER.clearMutables();
BiomeAPI.NETHER_BIOME_PICKER.clearMutables();
this.possibleBiomes().forEach(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (!BiomeAPI.hasBiome(key)) {
BCLBiome bclBiome = new BCLBiome(key, biome.value());
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
}
else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key)) {
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
}
}
}
}
});
BiomeAPI.NETHER_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.NETHER_BIOME_PICKER.rebuild();
initMap(0); this.possibleBiomes().forEach(biome -> {
} ResourceLocation key = biome.unwrapKey().orElseThrow().location();
@Override
public void setSeed(long seed) { if (!BiomeAPI.hasBiome(key)) {
seed = 0; BCLBiome bclBiome = new BCLBiome(key, biome.value());
super.setSeed(seed); BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
initMap(seed); } else {
BCLBiome bclBiome = BiomeAPI.getBiome(key);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (!BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key)) {
BiomeAPI.NETHER_BIOME_PICKER.addBiomeMutable(bclBiome);
}
}
}
}
});
BiomeAPI.NETHER_BIOME_PICKER.getBiomes().forEach(biome -> biome.updateActualBiomes(biomeRegistry));
BiomeAPI.NETHER_BIOME_PICKER.rebuild();
} }
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, long seed) {
this(biomeRegistry);
setSeed(seed);
}
/**
* When true, the older square generator is used for the nether.
* <p>
* This override is used (for example) by BetterNether to force the legacy generation for worlds
* that were created before 1.18
*
* @param val wether or not you want to force the old generatore.
*/
public static void setForceLegacyGeneration(boolean val) {
forceLegacyGenerator = val;
}
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) { /**
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class).getValue(); * Set world height, used when Nether is larger than vanilla 128 blocks tall.
*
* @param worldHeight height of the Nether ceiling.
*/
public static void setWorldHeight(int worldHeight) {
BCLibNetherBiomeSource.worldHeight = worldHeight;
}
return biomeRegistry.stream() private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
.filter(biome -> biomeRegistry.getResourceKey(biome).isPresent()) List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class)
.map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get())) .getValue();
.filter(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (include.contains(key.toString())) { return biomeRegistry.stream()
return true; .filter(biome -> biomeRegistry.getResourceKey(biome).isPresent())
} .map(biome -> biomeRegistry.getOrCreateHolder(biomeRegistry.getResourceKey(biome).get()))
.filter(biome -> {
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
if (GeneratorOptions.addNetherBiomesByTag() && biome.is(BiomeTags.IS_NETHER)) { if (include.contains(key.toString())) {
return true; return true;
} }
BCLBiome bclBiome = BiomeAPI.getBiome(key); if (GeneratorOptions.addNetherBiomesByTag() && biome.is(BiomeTags.IS_NETHER)) {
if (bclBiome != BiomeAPI.EMPTY_BIOME) { return true;
if (bclBiome.getParentBiome() != null) { }
bclBiome = bclBiome.getParentBiome();
}
key = bclBiome.getID();
}
final boolean isNetherBiome = biome.is(BiomeTags.IS_NETHER);
return BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key) || (isNetherBiome && BiomeAPI.isDatapackBiome(key));
}).toList();
}
@Override
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler var4) {
if (biomeMap==null)
return this.possibleBiomes().stream().findFirst().get();
if (lastWorldHeight != worldHeight) { BCLBiome bclBiome = BiomeAPI.getBiome(key);
lastWorldHeight = worldHeight; if (bclBiome != BiomeAPI.EMPTY_BIOME) {
initMap(this.currentSeed); if (bclBiome.getParentBiome() != null) {
} bclBiome = bclBiome.getParentBiome();
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) { }
biomeMap.clearCache(); key = bclBiome.getID();
} }
BCLBiome bb = biomeMap.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2); final boolean isNetherBiome = biome.is(BiomeTags.IS_NETHER);
if(biomeRegistry.getId(bb.getActualBiome().value())<0) debug(bb, biomeRegistry); return BiomeAPI.NETHER_BIOME_PICKER.containsImmutable(key) || (isNetherBiome && BiomeAPI.isDatapackBiome(
return bb.getActualBiome(); key));
} }).toList();
}
public static<T> void debug(Object el, Registry<T> reg){ public static <T> void debug(Object el, Registry<T> reg) {
System.out.println("Unknown " + el + " in " + reg); System.out.println("Unknown " + el + " in " + reg);
} }
@Override public static void register() {
protected Codec<? extends BiomeSource> codec() { Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("nether_biome_source"), CODEC);
return CODEC; }
}
@Override
public static void register() { public void setSeed(long seed) {
Registry.register(Registry.BIOME_SOURCE, BCLib.makeID("nether_biome_source"), CODEC);
} super.setSeed(seed);
initMap(seed);
private void initMap(long seed) { }
boolean useLegacy = GeneratorOptions.useOldBiomeGenerator() || forceLegacyGenerator;
TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor = useLegacy ? SquareBiomeMap::new : HexBiomeMap::new; @Override
if (worldHeight > 128 && GeneratorOptions.useVerticalBiomes()) { public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler var4) {
this.biomeMap = new MapStack( if (biomeMap == null)
seed, return this.possibleBiomes().stream().findFirst().get();
GeneratorOptions.getBiomeSizeNether(),
BiomeAPI.NETHER_BIOME_PICKER, if (lastWorldHeight != worldHeight) {
GeneratorOptions.getVerticalBiomeSizeNether(), lastWorldHeight = worldHeight;
worldHeight, initMap(this.currentSeed);
mapConstructor }
); if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
} biomeMap.clearCache();
else { }
this.biomeMap = mapConstructor.apply(seed, GeneratorOptions.getBiomeSizeNether(), BiomeAPI.NETHER_BIOME_PICKER); BCLBiome bb = biomeMap.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2);
} return bb.getActualBiome();
} }
@Override @Override
public String toString() { protected Codec<? extends BiomeSource> codec() {
return "BCLib - Nether BiomeSource"; return CODEC;
} }
private void initMap(long seed) {
boolean useLegacy = GeneratorOptions.useOldBiomeGenerator() || forceLegacyGenerator;
TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor = useLegacy
? SquareBiomeMap::new
: HexBiomeMap::new;
if (worldHeight > 128 && GeneratorOptions.useVerticalBiomes()) {
this.biomeMap = new MapStack(
seed,
GeneratorOptions.getBiomeSizeNether(),
BiomeAPI.NETHER_BIOME_PICKER,
GeneratorOptions.getVerticalBiomeSizeNether(),
worldHeight,
mapConstructor
);
} else {
this.biomeMap = mapConstructor.apply(seed,
GeneratorOptions.getBiomeSizeNether(),
BiomeAPI.NETHER_BIOME_PICKER);
}
}
@Override
public String toString() {
return "BCLib - Nether BiomeSource";
}
} }