[Change] Change handling of End Biomes once more. (EndSource will consider Barrens and MainIsland biomes as well now)

This commit is contained in:
Frank 2022-07-02 14:33:52 +02:00
parent e411dc10d9
commit e35fe997c1
15 changed files with 714 additions and 334 deletions

View file

@ -4,7 +4,6 @@ import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import org.betterx.bclib.config.ConfigKeeper.StringArrayEntry;
import org.betterx.bclib.config.Configs;
import org.betterx.bclib.interfaces.BiomeMap;
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
@ -26,9 +25,8 @@ import net.minecraft.world.level.biome.Climate;
import net.minecraft.world.level.levelgen.DensityFunction;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.function.BiFunction;
import org.jetbrains.annotations.NotNull;
@ -54,15 +52,17 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
instance.stable(BCLibEndBiomeSource::new)
)
);
private final Holder<Biome> centerBiome;
private final Holder<Biome> barrens;
private final Point pos;
private final BiFunction<Point, Integer, Boolean> endLandFunction;
private BiomeMap mapLand;
private BiomeMap mapVoid;
private BiomeMap mapCenter;
private BiomeMap mapBarrens;
private final BiomePicker endLandBiomePicker;
private final BiomePicker endVoidBiomePicker;
private final BiomePicker endCenterBiomePicker;
private final BiomePicker endBarrensBiomePicker;
private BCLEndBiomeSourceConfig config;
@ -92,81 +92,79 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
) {
super(biomeRegistry, list, seed);
this.config = config;
var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap();
var excludeList = Configs.BIOMES_CONFIG.getBiomeExcludeMap().get(BiomeAPI.BiomeType.END);
endLandBiomePicker = new BiomePicker(biomeRegistry);
endVoidBiomePicker = new BiomePicker(biomeRegistry);
endCenterBiomePicker = new BiomePicker(biomeRegistry);
endBarrensBiomePicker = new BiomePicker(biomeRegistry);
Map<BiomeAPI.BiomeType, BiomePicker> pickerMap = new HashMap<>();
pickerMap.put(BiomeAPI.BiomeType.END_LAND, endLandBiomePicker);
pickerMap.put(BiomeAPI.BiomeType.END_VOID, endVoidBiomePicker);
pickerMap.put(BiomeAPI.BiomeType.END_CENTER, endCenterBiomePicker);
pickerMap.put(BiomeAPI.BiomeType.END_BARRENS, endBarrensBiomePicker);
List<String> includeVoid = Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_void_biomes",
StringArrayEntry.class
).getValue();
List<String> includeLand = Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_land_biomes",
StringArrayEntry.class
).getValue();
this.possibleBiomes().forEach(biome -> {
ResourceKey<Biome> key = biome.unwrapKey().orElseThrow();
ResourceLocation biomeID = key.location();
String biomeStr = biomeID.toString();
//exclude everything that was listed
if (excludeList != null && excludeList.contains(biomeStr)) return;
final BCLBiome bclBiome;
if (!BiomeAPI.hasBiome(biomeID)) {
BCLBiome bclBiome = new BCLBiome(biomeID, biome.value());
if (includeVoid.contains(biomeID.toString())) {
endVoidBiomePicker.addBiome(bclBiome);
} else {
endLandBiomePicker.addBiome(bclBiome);
}
bclBiome = new BCLBiome(biomeID, biome.value());
} else {
BCLBiome bclBiome = BiomeAPI.getBiome(biomeID);
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
if (config.withVoidBiomes) {
if (biomeID.equals(Biomes.THE_END.location())) {
//we discard those Biomes
} else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID)
|| biomeID.equals(Biomes.SMALL_END_ISLANDS.location())
|| TheEndBiomesHelper.isIntendedForEndBarrens(key)
|| includeVoid.contains(biomeID.toString())
) {
endVoidBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID)
|| TheEndBiomesHelper.isIntendedForEndLand(key)
|| includeLand.contains(biomeID.toString())
) {
endLandBiomePicker.addBiome(bclBiome);
}
} else {
if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location())
|| biomeID.equals(Biomes.THE_END.location())
) {
//we discard those Biomes
} else if (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID)
|| TheEndBiomesHelper.isIntendedForEndLand(key)
|| includeLand.contains(biomeID.toString())
) {
endLandBiomePicker.addBiome(bclBiome);
endVoidBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString())) {
endVoidBiomePicker.addBiome(bclBiome);
}
bclBiome = BiomeAPI.getBiome(biomeID);
}
if (bclBiome != null || bclBiome != BiomeAPI.EMPTY_BIOME) {
if (bclBiome.getParentBiome() == null) {
//ignore small islands when void biomes are disabled
if (!config.withVoidBiomes) {
if (biomeID.equals(Biomes.SMALL_END_ISLANDS.location())) {
return;
}
}
//force include biomes
boolean didForceAdd = false;
for (var entry : pickerMap.entrySet()) {
var includeList = includeMap == null ? null : includeMap.get(entry.getKey());
if (includeList != null && includeList.contains(biomeStr)) {
entry.getValue().addBiome(bclBiome);
didForceAdd = true;
}
}
if (!didForceAdd) {
if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_CENTER)
|| TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) {
endCenterBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_LAND)
|| TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) {
if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome);
endLandBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_BARRENS)
|| TheEndBiomesHelper.canGenerateAsEndBarrens(key)) {
endBarrensBiomePicker.addBiome(bclBiome);
} else if (BiomeAPI.wasRegisteredAs(biomeID, BiomeAPI.BiomeType.END_VOID)
|| TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) {
endVoidBiomePicker.addBiome(bclBiome);
}
}
}
}
});
});
endLandBiomePicker.rebuild();
endVoidBiomePicker.rebuild();
this.centerBiome = biomeRegistry.getOrCreateHolderOrThrow(Biomes.THE_END);
this.barrens = biomeRegistry.getOrCreateHolderOrThrow(Biomes.END_BARRENS);
endBarrensBiomePicker.rebuild();
endCenterBiomePicker.rebuild();
this.endLandFunction = GeneratorOptions.getEndLandFunction();
this.pos = new Point();
@ -188,51 +186,37 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
}
private static List<Holder<Biome>> getBclBiomes(Registry<Biome> biomeRegistry) {
List<String> include = Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_land_biomes",
StringArrayEntry.class
).getValue();
include.addAll(Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_void_biomes",
StringArrayEntry.class
).getValue());
return getBiomes(
biomeRegistry,
new ArrayList<>(0),
include,
Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END),
BCLibEndBiomeSource::isValidNonVanillaEndBiome
);
}
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
List<String> include = Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_land_biomes",
StringArrayEntry.class
).getValue();
include.addAll(Configs.BIOMES_CONFIG.getEntry(
"force_include",
"end_void_biomes",
StringArrayEntry.class
).getValue());
return getBiomes(biomeRegistry, new ArrayList<>(0), include, BCLibEndBiomeSource::isValidEndBiome);
return getBiomes(
biomeRegistry,
new ArrayList<>(0),
Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END),
BCLibEndBiomeSource::isValidEndBiome
);
}
private static boolean isValidEndBiome(Holder<Biome> biome, ResourceLocation location) {
return biome.is(BiomeTags.IS_END) ||
BiomeAPI.wasRegisteredAsEndBiome(location) ||
TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null));
TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null));
}
private static boolean isValidNonVanillaEndBiome(Holder<Biome> biome, ResourceLocation location) {
return biome.is(BiomeTags.IS_END) ||
BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_LAND) ||
BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_VOID) ||
TheEndBiomesHelper.isIntendedForAny(biome.unwrapKey().orElse(null));
BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_CENTER) ||
BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.BCL_END_BARRENS) ||
TheEndBiomesHelper.canGenerateInEnd(biome.unwrapKey().orElse(null));
}
public static void register() {
@ -243,15 +227,27 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
protected void onInitMap(long seed) {
this.mapLand = config.mapVersion.mapBuilder.apply(
seed,
GeneratorOptions.getBiomeSizeEndLand(),
config.landBiomesSize,
endLandBiomePicker
);
this.mapVoid = config.mapVersion.mapBuilder.apply(
seed,
GeneratorOptions.getBiomeSizeEndVoid(),
config.voidBiomesSize,
endVoidBiomePicker
);
this.mapCenter = config.mapVersion.mapBuilder.apply(
seed,
config.centerBiomesSize,
endCenterBiomePicker
);
this.mapBarrens = config.mapVersion.mapBuilder.apply(
seed,
config.barrensBiomesSize,
endBarrensBiomePicker
);
}
@Override
@ -261,7 +257,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
@Override
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.@NotNull Sampler sampler) {
if (mapLand == null || mapVoid == null)
if (mapLand == null || mapVoid == null || mapCenter == null || mapBarrens == null)
return this.possibleBiomes().stream().findFirst().orElseThrow();
int posX = QuartPos.toBlock(biomeX);
@ -275,32 +271,38 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
mapLand.clearCache();
mapVoid.clearCache();
mapCenter.clearCache();
mapVoid.clearCache();
}
if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) {
if (dist <= (long) config.innerVoidRadiusSquared) {
return this.centerBiome;
return mapCenter.getBiome(posX, biomeY << 2, posZ).biome;
}
int x = (SectionPos.blockToSectionCoord(posX) * 2 + 1) * 8;
int z = (SectionPos.blockToSectionCoord(posZ) * 2 + 1) * 8;
double d = sampler.erosion().compute(new DensityFunction.SinglePointContext(x, posY, z));
if (d > 0.25) {
return mapLand.getBiome(posX, biomeY << 2, posZ).biome;
return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //highlands
} else if (d >= -0.0625) {
return mapLand.getBiome(posX, biomeY << 2, posZ).biome;
return mapLand.getBiome(posX, biomeY << 2, posZ).biome; //midlands
} else {
return d < -0.21875
? mapVoid.getBiome(posX, biomeY << 2, posZ).biome
: config.withVoidBiomes ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
? mapVoid.getBiome(posX, biomeY << 2, posZ).biome //small islands
: (config.withVoidBiomes ? mapBarrens : mapLand).getBiome(
posX,
biomeY << 2,
posZ
).biome; //barrens
}
} else {
pos.setLocation(biomeX, biomeZ);
if (endLandFunction.apply(pos, maxHeight)) {
return dist <= (long) config.innerVoidRadiusSquared
? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome;
return (dist <= (long) config.innerVoidRadiusSquared ? mapCenter : mapLand)
.getBiome(posX, biomeY << 2, posZ).biome;
} else {
return dist <= (long) config.innerVoidRadiusSquared
? barrens
: mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
return (dist <= (long) config.innerVoidRadiusSquared ? mapBarrens : mapVoid)
.getBiome(posX, biomeY << 2, posZ).biome;
}
}

View file

@ -11,8 +11,6 @@ import java.util.function.Function;
public class GeneratorOptions {
private static int biomeSizeNether;
private static int biomeVSizeNether;
private static int biomeSizeEndLand;
private static int biomeSizeEndVoid;
private static BiFunction<Point, Integer, Boolean> endLandFunction;
private static boolean customNetherBiomeSource = true;
private static boolean customEndBiomeSource = true;
@ -28,8 +26,6 @@ public class GeneratorOptions {
"biomeVerticalSize(onlyInTallNether)",
86
);
biomeSizeEndLand = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeLand", 256);
biomeSizeEndVoid = Configs.GENERATOR_CONFIG.getInt("end.biomeMap", "biomeSizeVoid", 256);
customNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customNetherBiomeSource", true);
customEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options", "customEndBiomeSource", true);
verticalBiomes = Configs.GENERATOR_CONFIG.getBoolean("options", "verticalBiomesInTallNether", true);
@ -45,12 +41,14 @@ public class GeneratorOptions {
return Mth.clamp(biomeVSizeNether, 1, 8192);
}
@Deprecated(forRemoval = true)
public static int getBiomeSizeEndLand() {
return Mth.clamp(biomeSizeEndLand, 1, 8192);
return 256;
}
@Deprecated(forRemoval = true)
public static int getBiomeSizeEndVoid() {
return Mth.clamp(biomeSizeEndVoid, 1, 8192);
return 256;
}
/**

View file

@ -1,97 +1,92 @@
package org.betterx.bclib.api.v2.generator;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.jetbrains.annotations.ApiStatus;
/**
* Helper class until FAPI integrates https://github.com/FabricMC/fabric/pull/2369
* Helper class until FAPI integrates <a href="https://github.com/FabricMC/fabric/pull/2369">this PR</a>
*/
public class TheEndBiomesHelper {
public static TheEndBiomeDataAccessor INSTANCE;
@ApiStatus.Internal
public static Map<BiomeAPI.BiomeType, Set<ResourceKey<Biome>>> END_BIOMES = new HashMap<>();
private static TheEndBiomeDataAccessor get() {
if (INSTANCE == null) {
try {
Class<TheEndBiomeData> cl = TheEndBiomeData.class;
Constructor constr = Arrays.stream(cl.getDeclaredConstructors())
.filter(c -> c.getParameterCount() == 0)
.findFirst()
.orElseThrow();
constr.setAccessible(true);
INSTANCE = (TheEndBiomeDataAccessor) constr.newInstance();
} catch (NoClassDefFoundError cnf) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
if (INSTANCE == null) {
BCLib.LOGGER.warning("Unable to access internal End-Biome API from Fabric. Using Fallback behaviour.");
INSTANCE = new TheEndBiomeDataAccessor() {
@Override
public boolean bcl_canGenerateAsEndBiome(ResourceKey<Biome> key) {
return true;
}
@Override
public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey<Biome> key) {
return false;
}
@Override
public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey<Biome> key) {
return false;
}
};
}
}
return INSTANCE;
@ApiStatus.Internal
public static void add(BiomeAPI.BiomeType type, ResourceKey<Biome> biome) {
if (biome == null) return;
END_BIOMES.computeIfAbsent(type, t -> new HashSet<>()).add(biome);
}
private static boolean has(BiomeAPI.BiomeType type, ResourceKey<Biome> biome) {
if (biome == null) return false;
Set<ResourceKey<Biome>> set = END_BIOMES.get(type);
if (set == null) return false;
return set.contains(biome);
}
/**
* Returns true if the given biome was added in the end, considering the Vanilla end biomes,
* Returns true if the given biome was added as a main end Biome in the end, considering the Vanilla end biomes,
* and any biomes added to the End by mods.
*
* @param biome The biome to search for
*/
public static boolean isIntendedForEndBiome(ResourceKey<Biome> biome) {
return get().bcl_canGenerateAsEndBiome(biome);
public static boolean canGenerateAsMainIslandBiome(ResourceKey<Biome> biome) {
return has(BiomeAPI.BiomeType.END_CENTER, biome);
}
/**
* Returns true if the given biome was added as a small end islands Biome in the end, considering the Vanilla end biomes,
* and any biomes added to the End by mods.
*
* @param biome The biome to search for
*/
public static boolean canGenerateAsSmallIslandsBiome(ResourceKey<Biome> biome) {
return has(BiomeAPI.BiomeType.END_VOID, biome);
}
/**
* Returns true if the given biome was added as a Highland Biome in the end, considering the Vanilla end biomes,
* and any biomes added to the End by mods.
*
* @param biome The biome to search for
*/
public static boolean canGenerateAsHighlandsBiome(ResourceKey<Biome> biome) {
return has(BiomeAPI.BiomeType.END_LAND, biome);
}
/**
* Returns true if the given biome was added as midland biome in the end, considering the Vanilla end biomes,
* and any biomes added to the End as midland biome by mods.
*
* @param biome The biome to search for
*/
public static boolean isIntendedForEndMidlands(ResourceKey<Biome> biome) {
return get().bcl_canGenerateAsEndMidlandBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome);
public static boolean canGenerateAsEndMidlands(ResourceKey<Biome> biome) {
return false;
}
/**
* Returns true if the given biome was added as barrens biome in the end, considering the Vanilla end biomes,
* and any biomes added to the End as barrens biome by mods.
*
* @param biome The biome to search for
*/
public static boolean isIntendedForEndBarrens(ResourceKey<Biome> biome) {
return get().bcl_canGenerateAsEndBarrensBiome(biome) && !get().bcl_canGenerateAsEndBiome(biome) && !get().bcl_canGenerateAsEndMidlandBiome(
biome);
public static boolean canGenerateAsEndBarrens(ResourceKey<Biome> biome) {
return has(BiomeAPI.BiomeType.END_BARRENS, biome);
}
public static boolean isIntendedForEndLand(ResourceKey<Biome> biome) {
return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome);
}
public static boolean isIntendedForAny(ResourceKey<Biome> biome) {
return isIntendedForEndBiome(biome) || isIntendedForEndMidlands(biome) || isIntendedForEndBarrens(biome);
public static boolean canGenerateInEnd(ResourceKey<Biome> biome) {
return canGenerateAsHighlandsBiome(biome)
|| canGenerateAsEndBarrens(biome)
|| canGenerateAsEndMidlands(biome)
|| canGenerateAsSmallIslandsBiome(biome)
|| canGenerateAsMainIslandBiome(biome);
}
}

View file

@ -10,6 +10,7 @@ import org.betterx.worlds.together.biomesource.config.BiomeSourceConfig;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.util.Mth;
import net.minecraft.util.StringRepresentable;
import java.util.Objects;
@ -20,19 +21,31 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
EndBiomeMapType.VANILLA,
EndBiomeGeneratorType.VANILLA,
true,
4096
4096,
128,
128,
128,
128
);
public static final BCLEndBiomeSourceConfig MINECRAFT_17 = new BCLEndBiomeSourceConfig(
EndBiomeMapType.SQUARE,
EndBiomeGeneratorType.PAULEVS,
true,
1000000
1000000,
256,
256,
256,
256
);
public static final BCLEndBiomeSourceConfig MINECRAFT_18 = new BCLEndBiomeSourceConfig(
EndBiomeMapType.HEX,
EndBiomeGeneratorType.PAULEVS,
true,
MINECRAFT_17.innerVoidRadiusSquared
MINECRAFT_17.innerVoidRadiusSquared,
MINECRAFT_17.centerBiomesSize,
MINECRAFT_17.voidBiomesSize,
MINECRAFT_17.landBiomesSize,
MINECRAFT_17.barrensBiomesSize
);
public static final BCLEndBiomeSourceConfig DEFAULT = MINECRAFT_18;
@ -53,7 +66,23 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
Codec.INT
.fieldOf("inner_void_radius_squared")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.innerVoidRadiusSquared)
.forGetter(o -> o.innerVoidRadiusSquared),
Codec.INT
.fieldOf("center_biomes_size")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.centerBiomesSize),
Codec.INT
.fieldOf("void_biomes_size")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.voidBiomesSize),
Codec.INT
.fieldOf("land_biomes_size")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.landBiomesSize),
Codec.INT
.fieldOf("barrens_biomes_size")
.orElse(DEFAULT.innerVoidRadiusSquared)
.forGetter(o -> o.barrensBiomesSize)
)
.apply(instance, BCLEndBiomeSourceConfig::new));
@ -61,12 +90,20 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
@NotNull EndBiomeMapType mapVersion,
@NotNull EndBiomeGeneratorType generatorVersion,
boolean withVoidBiomes,
int innerVoidRadiusSquared
int innerVoidRadiusSquared,
int centerBiomesSize,
int voidBiomesSize,
int landBiomesSize,
int barrensBiomesSize
) {
this.mapVersion = mapVersion;
this.generatorVersion = generatorVersion;
this.withVoidBiomes = withVoidBiomes;
this.innerVoidRadiusSquared = innerVoidRadiusSquared;
this.barrensBiomesSize = Mth.clamp(barrensBiomesSize, 1, 8192);
this.voidBiomesSize = Mth.clamp(voidBiomesSize, 1, 8192);
this.centerBiomesSize = Mth.clamp(centerBiomesSize, 1, 8192);
this.landBiomesSize = Mth.clamp(landBiomesSize, 1, 8192);
}
public enum EndBiomeMapType implements StringRepresentable {
@ -122,13 +159,22 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
public final boolean withVoidBiomes;
public final int innerVoidRadiusSquared;
public final int voidBiomesSize;
public final int centerBiomesSize;
public final int landBiomesSize;
public final int barrensBiomesSize;
@Override
public String toString() {
return "BCLibEndBiomeSourceConfig{" +
return "BCLEndBiomeSourceConfig{" +
"mapVersion=" + mapVersion +
", generatorVersion=" + generatorVersion +
", withVoidBiomes=" + withVoidBiomes +
", innerVoidRadiusSquared=" + innerVoidRadiusSquared +
", voidBiomesSize=" + voidBiomesSize +
", centerBiomesSize=" + centerBiomesSize +
", landBiomesSize=" + landBiomesSize +
", barrensBiomesSize=" + barrensBiomesSize +
'}';
}
@ -148,13 +194,22 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BCLEndBiomeSourceConfig)) return false;
if (o == null || getClass() != o.getClass()) return false;
BCLEndBiomeSourceConfig that = (BCLEndBiomeSourceConfig) o;
return withVoidBiomes == that.withVoidBiomes && innerVoidRadiusSquared == that.innerVoidRadiusSquared && mapVersion == that.mapVersion && generatorVersion == that.generatorVersion;
return withVoidBiomes == that.withVoidBiomes && innerVoidRadiusSquared == that.innerVoidRadiusSquared && voidBiomesSize == that.voidBiomesSize && centerBiomesSize == that.centerBiomesSize && landBiomesSize == that.landBiomesSize && barrensBiomesSize == that.barrensBiomesSize && mapVersion == that.mapVersion && generatorVersion == that.generatorVersion;
}
@Override
public int hashCode() {
return Objects.hash(mapVersion, generatorVersion, withVoidBiomes, innerVoidRadiusSquared);
return Objects.hash(
mapVersion,
generatorVersion,
withVoidBiomes,
innerVoidRadiusSquared,
voidBiomesSize,
centerBiomesSize,
landBiomesSize,
barrensBiomesSize
);
}
}

View file

@ -78,7 +78,11 @@ public class LevelGenEvents {
inputConfig.mapVersion,
BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA,
false,
inputConfig.innerVoidRadiusSquared
inputConfig.innerVoidRadiusSquared,
inputConfig.centerBiomesSize,
inputConfig.voidBiomesSize,
inputConfig.landBiomesSize,
inputConfig.barrensBiomesSize
));
}
}

View file

@ -114,6 +114,22 @@ public class BCLBiome extends BCLBiomeSettings {
return this;
}
/**
* Set biome edge for this biome instance. If there is already an edge, the
* biome is added as subBiome to the current edge-biome
*
* @param edge The new edge
* @return same {@link BCLBiome}.
*/
public BCLBiome addEdge(BCLBiome edge) {
if (this.edge != null) {
this.edge.addSubBiome(edge);
} else {
this.setEdge(edge);
}
return this;
}
/**
* Adds sub-biome into this biome instance. Biome chance will be interpreted as a sub-biome generation chance.
* Biome itself has chance 1.0 compared to all its sub-biomes.

View file

@ -64,27 +64,27 @@ public class BiomeAPI {
public static final BiomeType OVERWORLD = new BiomeType("OVERWORLD");
public static final BiomeType NETHER = new BiomeType("NETHER");
public static final BiomeType BCL_NETHER = new BiomeType("BCL_NETHER", NETHER);
public static final BiomeType OTHER_NETHER = new BiomeType("OTHER_NETHER", NETHER);
public static final BiomeType END = new BiomeType("END");
public static final BiomeType END_LAND = new BiomeType("END_LAND", END);
public static final BiomeType END_VOID = new BiomeType("END_VOID", END);
public static final BiomeType END_CENTER = new BiomeType("END_CENTER", END);
public static final BiomeType END_BARRENS = new BiomeType("END_BARRENS", END);
public static final BiomeType BCL_END_LAND = new BiomeType("BCL_END_LAND", END_LAND);
public static final BiomeType BCL_END_VOID = new BiomeType("BCL_END_VOID", END_VOID);
public static final BiomeType OTHER_END_LAND = new BiomeType("OTHER_END_LAND", END_LAND);
public static final BiomeType OTHER_END_VOID = new BiomeType("OTHER_END_VOID", END_VOID);
public static final BiomeType BCL_END_CENTER = new BiomeType("BCL_END_CENTER", END_CENTER);
public static final BiomeType BCL_END_BARRENS = new BiomeType("BCL_END_BARRENS", END_BARRENS);
static final Map<ResourceLocation, BiomeType> BIOME_TYPE_MAP = Maps.newHashMap();
public final BiomeType parentOrNull;
private final String debugName;
private final String name;
public BiomeType(String debugName) {
this(debugName, null);
public BiomeType(String name) {
this(name, null);
}
public BiomeType(String debugName, BiomeType parentOrNull) {
public BiomeType(String name, BiomeType parentOrNull) {
this.parentOrNull = parentOrNull;
this.debugName = debugName;
this.name = name;
}
public boolean is(BiomeType d) {
@ -93,9 +93,13 @@ public class BiomeAPI {
return false;
}
public String getName() {
return name;
}
@Override
public String toString() {
String str = debugName;
String str = name;
if (parentOrNull != null) str += " -> " + parentOrNull;
return str;
}
@ -109,28 +113,58 @@ public class BiomeAPI {
private static final Map<ResourceLocation, BCLBiome> ID_MAP = Maps.newHashMap();
public static final BCLBiome NETHER_WASTES_BIOME = registerNetherBiome(getFromRegistry(Biomes.NETHER_WASTES).value());
public static final BCLBiome CRIMSON_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.CRIMSON_FOREST).value());
public static final BCLBiome WARPED_FOREST_BIOME = registerNetherBiome(getFromRegistry(Biomes.WARPED_FOREST).value());
public static final BCLBiome SOUL_SAND_VALLEY_BIOME = registerNetherBiome(getFromRegistry(Biomes.SOUL_SAND_VALLEY).value());
public static final BCLBiome BASALT_DELTAS_BIOME = registerNetherBiome(getFromRegistry(Biomes.BASALT_DELTAS).value());
public static final BCLBiome THE_END = registerCenterBiome(getFromRegistry(Biomes.THE_END));
public static final BCLBiome END_HIGHLANDS = registerEndLandBiome(
getFromRegistry(Biomes.END_HIGHLANDS),
0.5F
public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome(
Biomes.NETHER_WASTES,
InternalBiomeAPI.OTHER_NETHER
);
public static final BCLBiome END_MIDLANDS = registerSubBiome(
END_HIGHLANDS,
getFromRegistry(Biomes.END_MIDLANDS).value(),
0.5F
public static final BCLBiome CRIMSON_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome(
Biomes.CRIMSON_FOREST,
InternalBiomeAPI.OTHER_NETHER
);
public static final BCLBiome WARPED_FOREST_BIOME = InternalBiomeAPI.wrapNativeBiome(
Biomes.WARPED_FOREST,
InternalBiomeAPI.OTHER_NETHER
);
public static final BCLBiome SOUL_SAND_VALLEY_BIOME = InternalBiomeAPI.wrapNativeBiome(
Biomes.SOUL_SAND_VALLEY,
InternalBiomeAPI.OTHER_NETHER
);
public static final BCLBiome BASALT_DELTAS_BIOME = InternalBiomeAPI.wrapNativeBiome(
Biomes.BASALT_DELTAS,
InternalBiomeAPI.OTHER_NETHER
);
public static final BCLBiome END_BARRENS = registerEndBiome(getFromRegistry(new ResourceLocation("end_barrens")));
public static final BCLBiome SMALL_END_ISLANDS = registerEndVoidBiome(getFromRegistry(new ResourceLocation(
"small_end_islands")));
public static final BCLBiome THE_END = InternalBiomeAPI.wrapNativeBiome(
Biomes.THE_END,
0.5F,
InternalBiomeAPI.OTHER_END_CENTER
);
public static final BCLBiome END_MIDLANDS = InternalBiomeAPI.wrapNativeBiome(
Biomes.END_MIDLANDS,
0.5F,
InternalBiomeAPI.OTHER_END_LAND
);
public static final BCLBiome END_HIGHLANDS = InternalBiomeAPI.wrapNativeBiome(
Biomes.END_HIGHLANDS,
END_MIDLANDS,
8,
0.5F,
InternalBiomeAPI.OTHER_END_LAND
);
public static final BCLBiome END_BARRENS = InternalBiomeAPI.wrapNativeBiome(
Biomes.END_BARRENS,
InternalBiomeAPI.OTHER_END_BARRENS
);
public static final BCLBiome SMALL_END_ISLANDS = InternalBiomeAPI.wrapNativeBiome(
Biomes.SMALL_END_ISLANDS,
InternalBiomeAPI.OTHER_END_VOID
);
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
@ -189,36 +223,6 @@ public class BiomeAPI {
return registerSubBiome(parent, subBiome, dim);
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
*
* @param bclBiome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerNetherBiome(BCLBiome bclBiome) {
registerBiome(bclBiome, BiomeType.BCL_NETHER);
ResourceKey<Biome> key = getBiomeKey(bclBiome.getBiome());
if (bclBiome.allowFabricRegistration()) {
bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
}
return bclBiome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerNetherBiome(Biome biome) {
BCLBiome bclBiome = new BCLBiome(biome, null);
registerBiome(bclBiome, BiomeType.OTHER_NETHER);
return bclBiome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
@ -232,47 +236,16 @@ public class BiomeAPI {
float weight = biome.getGenChance();
ResourceKey<Biome> key = getBiomeKey(biome.getBiome());
if (biome.allowFabricRegistration()) {
TheEndBiomes.addHighlandsBiome(key, weight);
TheEndBiomes.addMidlandsBiome(key, key, weight);
if (biome.isEdgeBiome()) {
ResourceKey<Biome> parentKey = getBiomeKey(biome.getParentBiome().getBiome());
TheEndBiomes.addMidlandsBiome(parentKey, key, weight);
} else {
TheEndBiomes.addHighlandsBiome(key, weight);
}
}
return biome;
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerEndLandBiome(Holder<Biome> biome) {
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
registerBiome(bclBiome, BiomeType.OTHER_END_LAND);
return bclBiome;
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome {@link BCLBiome};
* @param genChance float generation chance.
* @return {@link BCLBiome}
*/
public static BCLBiome registerEndLandBiome(Holder<Biome> biome, float genChance) {
BCLBiome bclBiome = new BCLBiome(
biome.value(),
VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
);
registerBiome(bclBiome, BiomeType.OTHER_END_LAND);
return bclBiome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
@ -294,18 +267,44 @@ public class BiomeAPI {
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands).
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a center island
* biome (will generate only on the center island).
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome) {
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
public static BCLBiome registerEndCenterBiome(BCLBiome biome) {
registerBiome(biome, BiomeType.BCL_END_CENTER);
registerBiome(bclBiome, BiomeType.OTHER_END_VOID);
return bclBiome;
float weight = biome.getGenChance();
ResourceKey<Biome> key = getBiomeKey(biome.getBiome());
if (biome.allowFabricRegistration()) {
TheEndBiomes.addMainIslandBiome(key, weight);
}
return biome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a barrens island
* biome (will generate on the edge of midland biomes on the larger islands).
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerEndBarrensBiome(BCLBiome highlandBiome, BCLBiome biome) {
registerBiome(biome, BiomeType.BCL_END_BARRENS);
float weight = biome.getGenChance();
ResourceKey<Biome> key = getBiomeKey(biome.getBiome());
if (biome.allowFabricRegistration()) {
ResourceKey<Biome> parentKey = getBiomeKey(highlandBiome.getBiome());
TheEndBiomes.addBarrensBiome(parentKey, key, weight);
}
return biome;
}
public static BCLBiome registerEndBiome(Holder<Biome> biome) {
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
@ -320,23 +319,6 @@ public class BiomeAPI {
return bclBiome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands).
*
* @param biome {@link BCLBiome}.
* @param genChance float generation chance.
* @return {@link BCLBiome}
*/
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome, float genChance) {
BCLBiome bclBiome = new BCLBiome(
biome.value(),
VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
);
registerBiome(bclBiome, BiomeType.OTHER_END_VOID);
return bclBiome;
}
/**
* Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes.
@ -532,6 +514,14 @@ public class BiomeAPI {
return wasRegisteredAs(biomeID, BiomeType.END_VOID);
}
public static boolean wasRegisteredAsEndCenterBiome(ResourceLocation biomeID) {
return wasRegisteredAs(biomeID, BiomeType.END_CENTER);
}
public static boolean wasRegisteredAsEndBarrensBiome(ResourceLocation biomeID) {
return wasRegisteredAs(biomeID, BiomeType.END_BARRENS);
}
/**
* Registers new biome modification for specified dimension. Will work both for mod and datapack biomes.
*
@ -845,4 +835,84 @@ public class BiomeAPI {
}
return features.get(index).stream().collect(Collectors.toList());
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
*
* @param bclBiome {@link BCLBiome}
* @return {@link BCLBiome}
*/
public static BCLBiome registerNetherBiome(BCLBiome bclBiome) {
registerBiome(bclBiome, BiomeType.BCL_NETHER);
ResourceKey<Biome> key = getBiomeKey(bclBiome.getBiome());
if (bclBiome.allowFabricRegistration()) {
bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
}
return bclBiome;
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
@Deprecated(forRemoval = true)
public static BCLBiome registerNetherBiome(Biome biome) {
return InternalBiomeAPI.wrapNativeBiome(biome, -1, InternalBiomeAPI.OTHER_NETHER);
}
@Deprecated(forRemoval = true)
public static BCLBiome registerEndLandBiome(Holder<Biome> biome) {
return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_LAND);
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands).
*
* @param biome {@link BCLBiome}
* @return {@link BCLBiome}
*/
@Deprecated(forRemoval = true)
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome) {
return InternalBiomeAPI.wrapNativeBiome(biome.unwrapKey().orElseThrow(), InternalBiomeAPI.OTHER_END_VOID);
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome {@link BCLBiome};
* @param genChance float generation chance.
* @return {@link BCLBiome}
*/
@Deprecated(forRemoval = true)
public static BCLBiome registerEndLandBiome(Holder<Biome> biome, float genChance) {
return InternalBiomeAPI.wrapNativeBiome(
biome.unwrapKey().orElseThrow(),
genChance,
InternalBiomeAPI.OTHER_END_LAND
);
}
/**
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a void biome (will generate only in the End void - between islands).
*
* @param biome {@link BCLBiome}.
* @param genChance float generation chance.
* @return {@link BCLBiome}
*/
@Deprecated(forRemoval = true)
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome, float genChance) {
return InternalBiomeAPI.wrapNativeBiome(
biome.unwrapKey().orElseThrow(),
genChance,
InternalBiomeAPI.OTHER_END_VOID
);
}
}

View file

@ -34,8 +34,30 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.stream.Stream;
import org.jetbrains.annotations.ApiStatus;
@ApiStatus.Internal
public class InternalBiomeAPI {
public static final BiomeAPI.BiomeType OTHER_NETHER = new BiomeAPI.BiomeType(
"OTHER_NETHER",
BiomeAPI.BiomeType.NETHER
);
public static final BiomeAPI.BiomeType OTHER_END_LAND = new BiomeAPI.BiomeType(
"OTHER_END_LAND",
BiomeAPI.BiomeType.END_LAND
);
public static final BiomeAPI.BiomeType OTHER_END_VOID = new BiomeAPI.BiomeType(
"OTHER_END_VOID",
BiomeAPI.BiomeType.END_VOID
);
public static final BiomeAPI.BiomeType OTHER_END_CENTER = new BiomeAPI.BiomeType(
"OTHER_END_CENTER",
BiomeAPI.BiomeType.END_CENTER
);
public static final BiomeAPI.BiomeType OTHER_END_BARRENS = new BiomeAPI.BiomeType(
"OTHER_END_BARRENS",
BiomeAPI.BiomeType.END_BARRENS
);
static final Map<Biome, BCLBiome> CLIENT = Maps.newHashMap();
static final Map<Holder<PlacedFeature>, Integer> FEATURE_ORDER = Maps.newHashMap();
static final MutableInt FEATURE_ORDER_ID = new MutableInt(0);
@ -246,6 +268,94 @@ public class InternalBiomeAPI {
private static final Set<ResourceLocation> BIOMES_TO_SORT = Sets.newHashSet();
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome The source biome to wrap
* @return {@link BCLBiome}
*/
public static BCLBiome wrapNativeBiome(ResourceKey<Biome> biome, BiomeAPI.BiomeType type) {
return wrapNativeBiome(biome, -1, type);
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome The source biome to wrap
* @param genChance generation chance. If <0 the default genChance is used
* @return {@link BCLBiome}
*/
public static BCLBiome wrapNativeBiome(ResourceKey<Biome> biome, float genChance, BiomeAPI.BiomeType type) {
return wrapNativeBiome(
biome,
genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build(),
type
);
}
public static BCLBiome wrapNativeBiome(
ResourceKey<Biome> biome,
BCLBiome edgeBiome,
int edgeBiomeSize,
float genChance,
BiomeAPI.BiomeType type
) {
VanillaBiomeSettings.Builder settings = VanillaBiomeSettings.createVanilla();
if (genChance >= 0) settings.setGenChance(genChance);
settings.setEdge(edgeBiome);
settings.setEdgeSize(edgeBiomeSize);
return wrapNativeBiome(biome, settings.build(), type);
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome The source biome to wrap
* @param setings the {@link VanillaBiomeSettings} to use
* @return {@link BCLBiome}
*/
private static BCLBiome wrapNativeBiome(
ResourceKey<Biome> biome,
VanillaBiomeSettings setings,
BiomeAPI.BiomeType type
) {
BCLBiome bclBiome = BiomeAPI.getBiome(biome.location());
if (bclBiome == BiomeAPI.EMPTY_BIOME) {
bclBiome = new BCLBiome(
BiomeAPI.getFromRegistry(biome).value(),
setings
);
}
BiomeAPI.registerBiome(bclBiome, type);
return bclBiome;
}
/**
* Register {@link BCLBiome} wrapper for {@link Biome}.
* After that biome will be added to BCLib End Biome Generator and into Fabric Biome API as a land biome (will generate only on islands).
*
* @param biome The source biome to wrap
* @param genChance generation chance.
* @return {@link BCLBiome}
*/
static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) {
BCLBiome bclBiome = BiomeAPI.getBiome(biome);
if (bclBiome == BiomeAPI.EMPTY_BIOME) {
bclBiome = new BCLBiome(
biome,
genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
);
}
BiomeAPI.registerBiome(bclBiome, type);
return bclBiome;
}
static {
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
Optional<? extends Registry<Biome>> oBiomeRegistry = registryManager.registry(Registry.BIOME_REGISTRY);

View file

@ -187,7 +187,11 @@ public class WorldSetupScreen extends BCLibScreen {
? BCLEndBiomeSourceConfig.EndBiomeGeneratorType.PAULEVS
: BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA,
generateEndVoid.isChecked(),
BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared
BCLEndBiomeSourceConfig.DEFAULT.innerVoidRadiusSquared,
BCLEndBiomeSourceConfig.DEFAULT.centerBiomesSize,
BCLEndBiomeSourceConfig.DEFAULT.voidBiomesSize,
BCLEndBiomeSourceConfig.DEFAULT.landBiomesSize,
BCLEndBiomeSourceConfig.DEFAULT.barrensBiomesSize
);
ChunkGenerator endGenerator = betterxDimensions.get(LevelStem.END);

View file

@ -0,0 +1,101 @@
package org.betterx.bclib.config;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
import java.util.*;
public class BiomesConfig extends PathConfig {
private Map<BiomeAPI.BiomeType, List<String>> BIOME_INCLUDE_LIST = null;
private Map<BiomeAPI.BiomeType, List<String>> BIOME_EXCLUDE_LIST = null;
public static final BiomeAPI.BiomeType[] endTypes = {
BiomeAPI.BiomeType.END_LAND,
BiomeAPI.BiomeType.END_VOID,
BiomeAPI.BiomeType.END_CENTER,
BiomeAPI.BiomeType.END_BARRENS
};
public static final BiomeAPI.BiomeType[] netherTypes = {
BiomeAPI.BiomeType.NETHER
};
private static final BiomeAPI.BiomeType[] includeTypes = all();
private static final BiomeAPI.BiomeType[] excludeTypes = {BiomeAPI.BiomeType.NETHER, BiomeAPI.BiomeType.END};
public BiomesConfig() {
super(BCLib.MOD_ID, "biomes", false);
for (var type : includeTypes) {
keeper.registerEntry(
new ConfigKey(type.getName(), "force_include"),
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
);
}
for (var type : excludeTypes) {
keeper.registerEntry(
new ConfigKey(type.getName(), "force_exclude"),
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
);
}
}
private static BiomeAPI.BiomeType[] all() {
BiomeAPI.BiomeType[] res = new BiomeAPI.BiomeType[endTypes.length + netherTypes.length];
System.arraycopy(netherTypes, 0, res, 0, netherTypes.length);
System.arraycopy(endTypes, 0, res, netherTypes.length, endTypes.length);
return res;
}
private List<String> getBiomeIncludeList(BiomeAPI.BiomeType type) {
var entry = getEntry(
"force_include",
type.getName(),
ConfigKeeper.StringArrayEntry.class
);
if (entry == null)
return List.of();
return entry.getValue();
}
private List<String> getBiomeExcludeList(BiomeAPI.BiomeType type) {
var entry = getEntry(
"force_exclude",
type.getName(),
ConfigKeeper.StringArrayEntry.class
);
if (entry == null)
return List.of();
return entry.getValue();
}
public List<String> getIncludeMatching(BiomeAPI.BiomeType type) {
return getBiomeIncludeMap().entrySet()
.stream()
.filter(e -> e.getKey().is(type))
.map(e -> e.getValue())
.flatMap(Collection::stream)
.toList();
}
public Map<BiomeAPI.BiomeType, List<String>> getBiomeIncludeMap() {
if (BIOME_INCLUDE_LIST == null) {
BIOME_INCLUDE_LIST = new HashMap<>();
for (BiomeAPI.BiomeType type : includeTypes) {
BIOME_INCLUDE_LIST.put(type, getBiomeIncludeList(type));
}
}
return BIOME_INCLUDE_LIST;
}
public Map<BiomeAPI.BiomeType, List<String>> getBiomeExcludeMap() {
if (BIOME_EXCLUDE_LIST == null) {
BIOME_EXCLUDE_LIST = new HashMap<>();
for (BiomeAPI.BiomeType type : excludeTypes) {
BIOME_EXCLUDE_LIST.put(type, getBiomeExcludeList(type));
}
}
return BIOME_EXCLUDE_LIST;
}
}

View file

@ -18,7 +18,7 @@ public class Configs {
public static final MainConfig MAIN_CONFIG = new MainConfig();
public static final PathConfig RECIPE_CONFIG = new PathConfig(BCLib.MOD_ID, "recipes");
public static final PathConfig BIOMES_CONFIG = new PathConfig(BCLib.MOD_ID, "biomes", false);
public static final BiomesConfig BIOMES_CONFIG = new BiomesConfig();
public static final String MAIN_PATCH_CATEGORY = "patches";
@ -29,6 +29,7 @@ public class Configs {
BIOMES_CONFIG.saveChanges();
}
static {
BIOMES_CONFIG.keeper.registerEntry(
new ConfigKey("end_land_biomes", "force_include"),

View file

@ -3,7 +3,7 @@ package org.betterx.bclib.interfaces;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
public interface TheEndBiomeDataAccessor {
public interface TheEndBiomesAccessor {
boolean bcl_canGenerateAsEndBiome(ResourceKey<Biome> key);
boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey<Biome> key);

View file

@ -1,40 +0,0 @@
package org.betterx.bclib.mixin.common;
import org.betterx.bclib.interfaces.TheEndBiomeDataAccessor;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
import net.fabricmc.fabric.impl.biome.WeightedPicker;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Map;
@Mixin(value = TheEndBiomeData.class, remap = false)
public class TheEndBiomeDataMixin implements TheEndBiomeDataAccessor {
@Shadow
@Final
private static Map<ResourceKey<Biome>, WeightedPicker<ResourceKey<Biome>>> END_BIOMES_MAP;
@Shadow
@Final
private static Map<ResourceKey<Biome>, WeightedPicker<ResourceKey<Biome>>> END_MIDLANDS_MAP;
@Shadow
@Final
private static Map<ResourceKey<Biome>, WeightedPicker<ResourceKey<Biome>>> END_BARRENS_MAP;
public boolean bcl_canGenerateAsEndBiome(ResourceKey<Biome> key) {
return END_BIOMES_MAP != null && END_BIOMES_MAP.containsKey(key);
}
public boolean bcl_canGenerateAsEndMidlandBiome(ResourceKey<Biome> key) {
return END_MIDLANDS_MAP != null && END_MIDLANDS_MAP.containsKey(key);
}
public boolean bcl_canGenerateAsEndBarrensBiome(ResourceKey<Biome> key) {
return END_BARRENS_MAP != null && END_BARRENS_MAP.containsKey(key);
}
}

View file

@ -0,0 +1,64 @@
package org.betterx.bclib.mixin.common;
import org.betterx.bclib.api.v2.generator.TheEndBiomesHelper;
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;
import net.fabricmc.fabric.api.biome.v1.TheEndBiomes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(value = TheEndBiomes.class, remap = false)
public class TheEndBiomesMixin {
@Inject(method = "addBarrensBiome", at = @At("HEAD"))
private static void bcl_registerBarrens(
ResourceKey<Biome> highlands,
ResourceKey<Biome> barrens,
double weight,
CallbackInfo ci
) {
TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_BARRENS, barrens);
}
@Inject(method = "addMidlandsBiome", at = @At("HEAD"))
private static void bcl_registerMidlands(
ResourceKey<Biome> highlands,
ResourceKey<Biome> midlands,
double weight,
CallbackInfo ci
) {
BCLBiome highland = InternalBiomeAPI.wrapNativeBiome(highlands, InternalBiomeAPI.OTHER_END_LAND);
BCLBiome midland = InternalBiomeAPI.wrapNativeBiome(midlands, InternalBiomeAPI.OTHER_END_LAND);
if (highland != null) {
highland.addEdge(midland);
}
TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, midlands);
}
@Inject(method = "addSmallIslandsBiome", at = @At("HEAD"))
private static void bcl_registerSmallIslands(
ResourceKey<Biome> biome, double weight, CallbackInfo ci
) {
TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_VOID, biome);
}
@Inject(method = "addHighlandsBiome", at = @At("HEAD"))
private static void bcl_registerHighlands(
ResourceKey<Biome> biome, double weight, CallbackInfo ci
) {
TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_LAND, biome);
}
@Inject(method = "addMainIslandBiome", at = @At("HEAD"))
private static void bcl_registerMainIsnalnd(
ResourceKey<Biome> biome, double weight, CallbackInfo ci
) {
TheEndBiomesHelper.add(InternalBiomeAPI.OTHER_END_CENTER, biome);
}
}

View file

@ -33,7 +33,7 @@
"ShovelItemAccessor",
"StructuresAccessor",
"SurfaceRulesContextAccessor",
"TheEndBiomeDataMixin",
"TheEndBiomesMixin",
"WorldGenRegionMixin",
"elytra.LivingEntityMixin",
"shears.BeehiveBlockMixin",