[Change] Removed BCLBiomeSource
This commit is contained in:
parent
3973a1a78f
commit
e80004efcf
19 changed files with 0 additions and 2383 deletions
|
@ -2,9 +2,6 @@ package org.betterx.bclib;
|
|||
|
||||
import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
|
||||
import org.betterx.bclib.api.v2.dataexchange.handler.autosync.*;
|
||||
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.GeneratorOptions;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenEvents;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
import org.betterx.bclib.api.v2.levelgen.structures.BCLStructurePoolElementTypes;
|
||||
|
@ -73,10 +70,7 @@ public class BCLib implements ModInitializer {
|
|||
BlockPredicates.ensureStaticInitialization();
|
||||
BCLBiomeRegistry.register();
|
||||
BaseRegistry.register();
|
||||
GeneratorOptions.init();
|
||||
BaseBlockEntities.register();
|
||||
BCLibEndBiomeSource.register();
|
||||
BCLibNetherBiomeSource.register();
|
||||
CraftingRecipes.init();
|
||||
BCLStructurePoolElementTypes.ensureStaticallyLoaded();
|
||||
WorldConfig.registerModCache(MOD_ID);
|
||||
|
|
|
@ -1,286 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceHelper;
|
||||
import org.betterx.worlds.together.biomesource.MergeableBiomeSource;
|
||||
import org.betterx.worlds.together.biomesource.ReloadableBiomeSource;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithSeed;
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource<BCLBiomeSource>, BiomeSourceWithNoiseRelatedSettings, ReloadableBiomeSource {
|
||||
@FunctionalInterface
|
||||
public interface PickerAdder {
|
||||
boolean add(BCLBiome bclBiome, BiomeAPI.BiomeType type, BiomePicker picker);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface CustomTypeFinder {
|
||||
BiomeAPI.BiomeType find(ResourceKey<Biome> biomeKey, BiomeAPI.BiomeType defaultType);
|
||||
}
|
||||
|
||||
protected long currentSeed;
|
||||
protected int maxHeight;
|
||||
private boolean didCreatePickers;
|
||||
Set<Holder<Biome>> dynamicPossibleBiomes;
|
||||
|
||||
protected BCLBiomeSource(long seed) {
|
||||
super();
|
||||
this.dynamicPossibleBiomes = Set.of();
|
||||
this.currentSeed = seed;
|
||||
this.didCreatePickers = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<Holder<Biome>> collectPossibleBiomes() {
|
||||
reloadBiomes();
|
||||
return dynamicPossibleBiomes.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Holder<Biome>> possibleBiomes() {
|
||||
return dynamicPossibleBiomes;
|
||||
}
|
||||
|
||||
|
||||
protected boolean wasBound() {
|
||||
return didCreatePickers;
|
||||
}
|
||||
|
||||
final public void setSeed(long seed) {
|
||||
if (seed != currentSeed) {
|
||||
BCLib.LOGGER.debug(this + "\n --> new seed = " + seed);
|
||||
this.currentSeed = seed;
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set world height
|
||||
*
|
||||
* @param maxHeight height of the World.
|
||||
*/
|
||||
final public void setMaxHeight(int maxHeight) {
|
||||
if (this.maxHeight != maxHeight) {
|
||||
BCLib.LOGGER.debug(this + "\n --> new height = " + maxHeight);
|
||||
this.maxHeight = maxHeight;
|
||||
onHeightChange(maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void initMap(long seed) {
|
||||
BCLib.LOGGER.debug(this + "\n --> Map Update");
|
||||
onInitMap(seed);
|
||||
}
|
||||
|
||||
protected abstract void onInitMap(long newSeed);
|
||||
protected abstract void onHeightChange(int newHeight);
|
||||
|
||||
|
||||
@NotNull
|
||||
protected String getNamespaces() {
|
||||
return BiomeSourceHelper.getNamespaces(possibleBiomes());
|
||||
}
|
||||
|
||||
protected boolean addToPicker(BCLBiome bclBiome, BiomeAPI.BiomeType type, BiomePicker picker) {
|
||||
picker.addBiome(bclBiome);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected BiomeAPI.BiomeType typeForUnknownBiome(ResourceKey<Biome> biomeKey, BiomeAPI.BiomeType defaultType) {
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
|
||||
protected static Set<Holder<Biome>> populateBiomePickers(
|
||||
Map<BiomeAPI.BiomeType, BiomePicker> acceptedBiomeTypes,
|
||||
BiomeAPI.BiomeType exclusionListType,
|
||||
PickerAdder pickerAdder,
|
||||
CustomTypeFinder typeFinder
|
||||
) {
|
||||
final RegistryAccess access = WorldBootstrap.getLastRegistryAccess();
|
||||
if (access == null) {
|
||||
if (Configs.MAIN_CONFIG.verboseLogging() && !BCLib.isDatagen()) {
|
||||
BCLib.LOGGER.info("Unable to build Biome List yet");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
final Set<Holder<Biome>> allBiomes = new HashSet<>();
|
||||
final Map<BiomeAPI.BiomeType, List<String>> includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap();
|
||||
final List<String> excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(exclusionListType);
|
||||
final Registry<Biome> biomes = access.registryOrThrow(Registries.BIOME);
|
||||
final Registry<BCLBiome> bclBiomes = access.registryOrThrow(BCLBiomeRegistry.BCL_BIOMES_REGISTRY);
|
||||
|
||||
final List<Map.Entry<ResourceKey<Biome>, Biome>> sortedList = biomes
|
||||
.entrySet()
|
||||
.stream()
|
||||
.sorted(Comparator.comparing(a -> a.getKey().location().toString()))
|
||||
.toList();
|
||||
|
||||
for (Map.Entry<ResourceKey<Biome>, Biome> biomeEntry : sortedList) {
|
||||
if (excludeList.contains(biomeEntry.getKey().location())) continue;
|
||||
|
||||
BiomeAPI.BiomeType type = BiomeAPI.BiomeType.NONE;
|
||||
boolean foundBCLBiome = false;
|
||||
if (BCLBiomeRegistry.hasBiome(biomeEntry.getKey(), bclBiomes)) {
|
||||
foundBCLBiome = true;
|
||||
type = BCLBiomeRegistry.getBiome(biomeEntry.getKey(), bclBiomes).getIntendedType();
|
||||
} else {
|
||||
type = typeFinder.find(biomeEntry.getKey(), type);
|
||||
}
|
||||
|
||||
type = getBiomeType(includeMap, biomeEntry.getKey(), type);
|
||||
|
||||
for (Map.Entry<BiomeAPI.BiomeType, BiomePicker> pickerEntry : acceptedBiomeTypes.entrySet()) {
|
||||
if (type.is(pickerEntry.getKey())) {
|
||||
BCLBiome bclBiome;
|
||||
if (foundBCLBiome) {
|
||||
bclBiome = BCLBiomeRegistry.getBiome(biomeEntry.getKey(), bclBiomes);
|
||||
} else {
|
||||
//create and register a biome wrapper
|
||||
bclBiome = new BCLBiome(biomeEntry.getKey().location(), type);
|
||||
BCLBiomeRegistry.register(bclBiome);
|
||||
foundBCLBiome = true;
|
||||
}
|
||||
|
||||
boolean isPossible;
|
||||
if (!bclBiome.hasParentBiome()) {
|
||||
isPossible = pickerAdder.add(bclBiome, pickerEntry.getKey(), pickerEntry.getValue());
|
||||
} else {
|
||||
isPossible = true;
|
||||
}
|
||||
|
||||
if (isPossible) {
|
||||
allBiomes.add(biomes.getHolderOrThrow(biomeEntry.getKey()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return allBiomes;
|
||||
}
|
||||
|
||||
protected abstract BiomeAPI.BiomeType defaultBiomeType();
|
||||
protected abstract Map<BiomeAPI.BiomeType, BiomePicker> createFreshPickerMap();
|
||||
|
||||
public abstract String toShortString();
|
||||
|
||||
protected void onFinishBiomeRebuild(Map<BiomeAPI.BiomeType, BiomePicker> pickerMap) {
|
||||
for (var picker : pickerMap.values()) {
|
||||
picker.rebuild();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void rebuildBiomes(boolean force) {
|
||||
if (!force && didCreatePickers) return;
|
||||
|
||||
if (Configs.MAIN_CONFIG.verboseLogging()) {
|
||||
BCLib.LOGGER.info("Updating Pickers for " + this.toShortString());
|
||||
}
|
||||
|
||||
Map<BiomeAPI.BiomeType, BiomePicker> pickerMap = createFreshPickerMap();
|
||||
this.dynamicPossibleBiomes = populateBiomePickers(
|
||||
pickerMap,
|
||||
defaultBiomeType(),
|
||||
this::addToPicker,
|
||||
this::typeForUnknownBiome
|
||||
);
|
||||
if (this.dynamicPossibleBiomes == null) {
|
||||
this.dynamicPossibleBiomes = Set.of();
|
||||
} else {
|
||||
this.didCreatePickers = true;
|
||||
}
|
||||
|
||||
onFinishBiomeRebuild(pickerMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLBiomeSource mergeWithBiomeSource(BiomeSource inputBiomeSource) {
|
||||
final RegistryAccess access = WorldBootstrap.getLastRegistryAccess();
|
||||
if (access == null) {
|
||||
BCLib.LOGGER.error("Unable to merge Biomesources!");
|
||||
return this;
|
||||
}
|
||||
|
||||
final Map<BiomeAPI.BiomeType, List<String>> includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap();
|
||||
final List<String> excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(defaultBiomeType());
|
||||
final Registry<BCLBiome> bclBiomes = access.registryOrThrow(BCLBiomeRegistry.BCL_BIOMES_REGISTRY);
|
||||
|
||||
try {
|
||||
for (Holder<Biome> possibleBiome : inputBiomeSource.possibleBiomes()) {
|
||||
ResourceKey<Biome> key = possibleBiome.unwrapKey().orElse(null);
|
||||
if (key != null) {
|
||||
//skip over all biomes that were excluded in the config
|
||||
if (excludeList.contains(key.location())) continue;
|
||||
|
||||
//this is a biome that has no type entry => create a new one for the default type of this registry
|
||||
if (!BCLBiomeRegistry.hasBiome(key, bclBiomes)) {
|
||||
BiomeAPI.BiomeType type = typeForUnknownBiome(key, defaultBiomeType());
|
||||
|
||||
//check if there was an override defined in the configs
|
||||
type = getBiomeType(includeMap, key, type);
|
||||
|
||||
//create and register a biome wrapper
|
||||
BCLBiome bclBiome = new BCLBiome(key.location(), type);
|
||||
BCLBiomeRegistry.register(bclBiome);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
BCLib.LOGGER.error("Error while rebuilding Biomesources!", e);
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Error while rebuilding Biomesources!", e);
|
||||
}
|
||||
|
||||
this.reloadBiomes();
|
||||
return this;
|
||||
}
|
||||
|
||||
private static BiomeAPI.BiomeType getBiomeType(
|
||||
Map<BiomeAPI.BiomeType, List<String>> includeMap,
|
||||
ResourceKey<Biome> biomeKey,
|
||||
BiomeAPI.BiomeType defaultType
|
||||
) {
|
||||
for (Map.Entry<BiomeAPI.BiomeType, List<String>> includeList : includeMap.entrySet()) {
|
||||
if (includeList.getValue().contains(biomeKey.location().toString())) {
|
||||
return includeList.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
public void onLoadGeneratorSettings(NoiseGeneratorSettings generator) {
|
||||
this.setMaxHeight(generator.noiseSettings().height());
|
||||
}
|
||||
|
||||
protected void reloadBiomes(boolean force) {
|
||||
rebuildBiomes(force);
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadBiomes() {
|
||||
reloadBiomes(true);
|
||||
}
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
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.Configs;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.QuartPos;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibEndBiomeSource, BCLEndBiomeSourceConfig> {
|
||||
public static Codec<BCLibEndBiomeSource> CODEC
|
||||
= RecordCodecBuilder.create((instance) -> instance
|
||||
.group(
|
||||
Codec
|
||||
.LONG
|
||||
.fieldOf("seed")
|
||||
.stable()
|
||||
.forGetter(source -> source.currentSeed),
|
||||
BCLEndBiomeSourceConfig
|
||||
.CODEC
|
||||
.fieldOf("config")
|
||||
.orElse(BCLEndBiomeSourceConfig.DEFAULT)
|
||||
.forGetter(o -> o.config)
|
||||
)
|
||||
.apply(
|
||||
instance,
|
||||
instance.stable(BCLibEndBiomeSource::new)
|
||||
)
|
||||
);
|
||||
private final Point pos;
|
||||
private BiomeMap mapLand;
|
||||
private BiomeMap mapVoid;
|
||||
private BiomeMap mapCenter;
|
||||
private BiomeMap mapBarrens;
|
||||
|
||||
private BiomePicker endLandBiomePicker;
|
||||
private BiomePicker endVoidBiomePicker;
|
||||
private BiomePicker endCenterBiomePicker;
|
||||
private BiomePicker endBarrensBiomePicker;
|
||||
private List<BiomeDecider> deciders;
|
||||
|
||||
private BCLEndBiomeSourceConfig config;
|
||||
|
||||
private BCLibEndBiomeSource(
|
||||
long seed,
|
||||
BCLEndBiomeSourceConfig config
|
||||
) {
|
||||
this(seed, config, true);
|
||||
}
|
||||
|
||||
public BCLibEndBiomeSource(
|
||||
BCLEndBiomeSourceConfig config
|
||||
) {
|
||||
this(0, config, false);
|
||||
}
|
||||
|
||||
|
||||
private BCLibEndBiomeSource(
|
||||
long seed,
|
||||
BCLEndBiomeSourceConfig config,
|
||||
boolean initMaps
|
||||
) {
|
||||
super(seed);
|
||||
this.config = config;
|
||||
rebuildBiomes(false);
|
||||
|
||||
this.pos = new Point();
|
||||
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiomeAPI.BiomeType defaultBiomeType() {
|
||||
return BiomeAPI.BiomeType.END_LAND;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<BiomeAPI.BiomeType, BiomePicker> createFreshPickerMap() {
|
||||
this.deciders = BiomeDecider.DECIDERS.stream()
|
||||
.filter(d -> d.canProvideFor(this))
|
||||
.map(d -> d.createInstance(this))
|
||||
.toList();
|
||||
|
||||
this.endLandBiomePicker = new BiomePicker();
|
||||
this.endVoidBiomePicker = new BiomePicker();
|
||||
this.endCenterBiomePicker = new BiomePicker();
|
||||
this.endBarrensBiomePicker = new BiomePicker();
|
||||
|
||||
return Map.of(
|
||||
BiomeAPI.BiomeType.END_LAND, endLandBiomePicker,
|
||||
BiomeAPI.BiomeType.END_VOID, endVoidBiomePicker,
|
||||
BiomeAPI.BiomeType.END_CENTER, endCenterBiomePicker,
|
||||
BiomeAPI.BiomeType.END_BARRENS, endBarrensBiomePicker
|
||||
);
|
||||
}
|
||||
|
||||
protected boolean addToPicker(BCLBiome bclBiome, BiomeAPI.BiomeType type, BiomePicker picker) {
|
||||
if (!config.withVoidBiomes) {
|
||||
if (bclBiome.getID().equals(Biomes.SMALL_END_ISLANDS.location())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (BiomeDecider decider : deciders) {
|
||||
if (decider.addToPicker(bclBiome)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.addToPicker(bclBiome, type, picker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiomeAPI.BiomeType typeForUnknownBiome(ResourceKey<Biome> biomeKey, BiomeAPI.BiomeType defaultType) {
|
||||
if (TheEndBiomesHelper.canGenerateAsMainIslandBiome(biomeKey)) {
|
||||
return BiomeAPI.BiomeType.END_CENTER;
|
||||
} else if (TheEndBiomesHelper.canGenerateAsHighlandsBiome(biomeKey)) {
|
||||
if (!config.withVoidBiomes) return BiomeAPI.BiomeType.END_VOID;
|
||||
return BiomeAPI.BiomeType.END_LAND;
|
||||
} else if (TheEndBiomesHelper.canGenerateAsEndBarrens(biomeKey)) {
|
||||
return BiomeAPI.BiomeType.END_BARRENS;
|
||||
} else if (TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(biomeKey)) {
|
||||
return BiomeAPI.BiomeType.END_VOID;
|
||||
} else if (TheEndBiomesHelper.canGenerateAsEndMidlands(biomeKey)) {
|
||||
return BiomeAPI.BiomeType.END_LAND;
|
||||
}
|
||||
|
||||
return super.typeForUnknownBiome(biomeKey, defaultType);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishBiomeRebuild(Map<BiomeAPI.BiomeType, BiomePicker> pickerMap) {
|
||||
super.onFinishBiomeRebuild(pickerMap);
|
||||
|
||||
for (BiomeDecider decider : deciders) {
|
||||
decider.rebuild();
|
||||
}
|
||||
|
||||
if (endVoidBiomePicker.isEmpty()) {
|
||||
if (Configs.MAIN_CONFIG.verboseLogging() && !BCLib.isDatagen())
|
||||
BCLib.LOGGER.info("No Void Biomes found. Disabling by using barrens");
|
||||
endVoidBiomePicker = endBarrensBiomePicker;
|
||||
}
|
||||
if (endBarrensBiomePicker.isEmpty()) {
|
||||
if (Configs.MAIN_CONFIG.verboseLogging() && !BCLib.isDatagen())
|
||||
BCLib.LOGGER.info("No Barrens Biomes found. Disabling by using land Biomes");
|
||||
endBarrensBiomePicker = endLandBiomePicker;
|
||||
endVoidBiomePicker = endLandBiomePicker;
|
||||
}
|
||||
if (endCenterBiomePicker.isEmpty()) {
|
||||
if (Configs.MAIN_CONFIG.verboseLogging() && !BCLib.isDatagen())
|
||||
BCLib.LOGGER.warning("No Center Island Biomes found. Forcing use of vanilla center.");
|
||||
endCenterBiomePicker.addBiome(BiomeAPI.THE_END);
|
||||
endCenterBiomePicker.rebuild();
|
||||
if (endCenterBiomePicker.isEmpty()) {
|
||||
if (Configs.MAIN_CONFIG.verboseLogging() && !BCLib.isDatagen())
|
||||
BCLib.LOGGER.error("Unable to force vanilla central Island. Falling back to land Biomes...");
|
||||
endCenterBiomePicker = endLandBiomePicker;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
Registry.register(BuiltInRegistries.BIOME_SOURCE, BCLib.makeID("end_biome_source"), CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitMap(long seed) {
|
||||
for (BiomeDecider decider : deciders) {
|
||||
decider.createMap((picker, size) -> config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
size <= 0 ? config.landBiomesSize : size,
|
||||
picker
|
||||
));
|
||||
}
|
||||
this.mapLand = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.landBiomesSize,
|
||||
endLandBiomePicker
|
||||
);
|
||||
|
||||
this.mapVoid = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.voidBiomesSize,
|
||||
endVoidBiomePicker
|
||||
);
|
||||
|
||||
this.mapCenter = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.centerBiomesSize,
|
||||
endCenterBiomePicker
|
||||
);
|
||||
|
||||
this.mapBarrens = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.barrensBiomesSize,
|
||||
endBarrensBiomePicker
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHeightChange(int newHeight) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.@NotNull Sampler sampler) {
|
||||
if (!wasBound()) reloadBiomes(false);
|
||||
|
||||
if (mapLand == null || mapVoid == null || mapCenter == null || mapBarrens == null)
|
||||
return this.possibleBiomes().stream().findFirst().orElseThrow();
|
||||
|
||||
int posX = QuartPos.toBlock(biomeX);
|
||||
int posY = QuartPos.toBlock(biomeY);
|
||||
int posZ = QuartPos.toBlock(biomeZ);
|
||||
|
||||
long dist = Math.abs(posX) + Math.abs(posZ) > (long) config.innerVoidRadiusSquared
|
||||
? ((long) config.innerVoidRadiusSquared + 1)
|
||||
: (long) posX * (long) posX + (long) posZ * (long) posZ;
|
||||
|
||||
|
||||
if ((biomeX & 63) == 0 || (biomeZ & 63) == 0) {
|
||||
mapLand.clearCache();
|
||||
mapVoid.clearCache();
|
||||
mapCenter.clearCache();
|
||||
mapVoid.clearCache();
|
||||
for (BiomeDecider decider : deciders) {
|
||||
decider.clearMapCache();
|
||||
}
|
||||
}
|
||||
|
||||
BiomeAPI.BiomeType suggestedType;
|
||||
|
||||
|
||||
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 (dist <= (long) config.innerVoidRadiusSquared) {
|
||||
suggestedType = BiomeAPI.BiomeType.END_CENTER;
|
||||
} else {
|
||||
if (d > 0.25) {
|
||||
suggestedType = BiomeAPI.BiomeType.END_LAND; //highlands
|
||||
} else if (d >= -0.0625) {
|
||||
suggestedType = BiomeAPI.BiomeType.END_LAND; //midlands
|
||||
} else {
|
||||
suggestedType = d < -0.21875
|
||||
? BiomeAPI.BiomeType.END_VOID //small islands
|
||||
: (config.withVoidBiomes
|
||||
? BiomeAPI.BiomeType.END_BARRENS
|
||||
: BiomeAPI.BiomeType.END_LAND); //barrens
|
||||
}
|
||||
}
|
||||
|
||||
final BiomeAPI.BiomeType originalType = suggestedType;
|
||||
for (BiomeDecider decider : deciders) {
|
||||
suggestedType = decider
|
||||
.suggestType(originalType, suggestedType, d, maxHeight, posX, posY, posZ, biomeX, biomeY, biomeZ);
|
||||
}
|
||||
|
||||
|
||||
BiomePicker.ActualBiome result;
|
||||
for (BiomeDecider decider : deciders) {
|
||||
if (decider.canProvideBiome(suggestedType)) {
|
||||
result = decider.provideBiome(suggestedType, posX, posY, posZ);
|
||||
if (result != null) return result.biome;
|
||||
}
|
||||
}
|
||||
|
||||
if (suggestedType.is(BiomeAPI.BiomeType.END_CENTER)) return mapCenter.getBiome(posX, posY, posZ).biome;
|
||||
if (suggestedType.is(BiomeAPI.BiomeType.END_VOID)) return mapVoid.getBiome(posX, posY, posZ).biome;
|
||||
if (suggestedType.is(BiomeAPI.BiomeType.END_BARRENS)) return mapBarrens.getBiome(posX, posY, posZ).biome;
|
||||
return mapLand.getBiome(posX, posY, posZ).biome;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Codec<? extends BiomeSource> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return "BCLib - The End BiomeSource (" + Integer.toHexString(hashCode()) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\n" + toShortString() +
|
||||
"\n biomes = " + possibleBiomes().size() +
|
||||
"\n namespaces = " + getNamespaces() +
|
||||
"\n seed = " + currentSeed +
|
||||
"\n height = " + maxHeight +
|
||||
"\n deciders = " + deciders.size() +
|
||||
"\n config = " + config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLEndBiomeSourceConfig getTogetherConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTogetherConfig(BCLEndBiomeSourceConfig newConfig) {
|
||||
this.config = newConfig;
|
||||
rebuildBiomes(true);
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.generator.config.MapBuilderFunction;
|
||||
import org.betterx.bclib.api.v2.generator.map.MapStack;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.NetherBiomes;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibNetherBiomeSource, BCLNetherBiomeSourceConfig> {
|
||||
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder
|
||||
.create(instance -> instance
|
||||
.group(
|
||||
Codec
|
||||
.LONG
|
||||
.fieldOf("seed")
|
||||
.stable()
|
||||
.forGetter(source -> {
|
||||
return source.currentSeed;
|
||||
}),
|
||||
BCLNetherBiomeSourceConfig
|
||||
.CODEC
|
||||
.fieldOf("config")
|
||||
.orElse(BCLNetherBiomeSourceConfig.DEFAULT)
|
||||
.forGetter(o -> o.config)
|
||||
)
|
||||
.apply(instance, instance.stable(BCLibNetherBiomeSource::new))
|
||||
);
|
||||
private BiomeMap biomeMap;
|
||||
private BiomePicker biomePicker;
|
||||
private BCLNetherBiomeSourceConfig config;
|
||||
|
||||
public BCLibNetherBiomeSource(
|
||||
BCLNetherBiomeSourceConfig config
|
||||
) {
|
||||
this(0, config, false);
|
||||
}
|
||||
|
||||
private BCLibNetherBiomeSource(
|
||||
long seed,
|
||||
BCLNetherBiomeSourceConfig config
|
||||
) {
|
||||
this(seed, config, true);
|
||||
}
|
||||
|
||||
|
||||
private BCLibNetherBiomeSource(
|
||||
long seed,
|
||||
BCLNetherBiomeSourceConfig config,
|
||||
boolean initMaps
|
||||
) {
|
||||
super(seed);
|
||||
this.config = config;
|
||||
rebuildBiomes(false);
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiomeAPI.BiomeType defaultBiomeType() {
|
||||
return BiomeAPI.BiomeType.NETHER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<BiomeAPI.BiomeType, BiomePicker> createFreshPickerMap() {
|
||||
this.biomePicker = new BiomePicker();
|
||||
return Map.of(defaultBiomeType(), this.biomePicker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BiomeAPI.BiomeType typeForUnknownBiome(ResourceKey<Biome> biomeKey, BiomeAPI.BiomeType defaultType) {
|
||||
//
|
||||
if (NetherBiomes.canGenerateInNether(biomeKey)) {
|
||||
return BiomeAPI.BiomeType.NETHER;
|
||||
}
|
||||
|
||||
return super.typeForUnknownBiome(biomeKey, defaultType);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
Registry.register(BuiltInRegistries.BIOME_SOURCE, BCLib.makeID("nether_biome_source"), CODEC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Biome> getNoiseBiome(int biomeX, int biomeY, int biomeZ, Climate.Sampler var4) {
|
||||
if (!wasBound()) reloadBiomes(false);
|
||||
|
||||
if (biomeMap == null)
|
||||
return this.possibleBiomes().stream().findFirst().get();
|
||||
|
||||
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
|
||||
biomeMap.clearCache();
|
||||
}
|
||||
BiomePicker.ActualBiome bb = biomeMap.getBiome(biomeX << 2, biomeY << 2, biomeZ << 2);
|
||||
return bb.biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Codec<? extends BiomeSource> codec() {
|
||||
return CODEC;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInitMap(long seed) {
|
||||
MapBuilderFunction mapConstructor = config.mapVersion.mapBuilder;
|
||||
if (maxHeight > config.biomeSizeVertical * 1.5 && config.useVerticalBiomes) {
|
||||
this.biomeMap = new MapStack(
|
||||
seed,
|
||||
config.biomeSize,
|
||||
biomePicker,
|
||||
config.biomeSizeVertical,
|
||||
maxHeight,
|
||||
mapConstructor
|
||||
);
|
||||
} else {
|
||||
this.biomeMap = mapConstructor.create(
|
||||
seed,
|
||||
config.biomeSize,
|
||||
biomePicker
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHeightChange(int newHeight) {
|
||||
initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toShortString() {
|
||||
return "BCLib - Nether BiomeSource (" + Integer.toHexString(hashCode()) + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\n" + toShortString() +
|
||||
"\n biomes = " + possibleBiomes().size() +
|
||||
"\n namespaces = " + getNamespaces() +
|
||||
"\n seed = " + currentSeed +
|
||||
"\n height = " + maxHeight +
|
||||
"\n config = " + config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BCLNetherBiomeSourceConfig getTogetherConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTogetherConfig(BCLNetherBiomeSourceConfig newConfig) {
|
||||
this.config = newConfig;
|
||||
initMap(currentSeed);
|
||||
}
|
||||
}
|
|
@ -1,266 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Used to extend the BiomePlacement in the {@link BCLBiomeSource}
|
||||
*/
|
||||
public abstract class BiomeDecider {
|
||||
|
||||
/**
|
||||
* used to create new {@link BiomeMap} instances
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BiomeMapBuilderFunction {
|
||||
/**
|
||||
* Constructs a new {@link BiomeMap}
|
||||
*
|
||||
* @param picker The picker the BiomeMap should use
|
||||
* @param biomeSize The biomeSize the map will use or -1 for the default size
|
||||
* @return a new {@link BiomeMap} instance
|
||||
*/
|
||||
BiomeMap create(BiomePicker picker, int biomeSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* used to determine wether or not a decider can provide this biome
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface BiomePredicate {
|
||||
boolean test(BCLBiome biome);
|
||||
}
|
||||
|
||||
protected BiomePicker picker;
|
||||
protected BiomeMap map;
|
||||
private final BiomePredicate predicate;
|
||||
|
||||
static List<BiomeDecider> DECIDERS = new LinkedList<>();
|
||||
|
||||
/**
|
||||
* Register a high priority Decider for the {@link BCLibEndBiomeSource}.
|
||||
* Normally you should not need to register a high priority decider and instead use
|
||||
* {@link BiomeDecider#registerDecider(ResourceLocation, BiomeDecider)}.
|
||||
* BetterEnd (for example) will add
|
||||
*
|
||||
* @param location The {@link ResourceLocation} for the decider
|
||||
* @param decider The initial decider Instance. Each Instance of the {@link BCLibEndBiomeSource}
|
||||
* will call {@link BiomeDecider#createInstance(BCLBiomeSource)} to build a
|
||||
* new instance of this decider
|
||||
*/
|
||||
public static void registerHighPriorityDecider(ResourceLocation location, BiomeDecider decider) {
|
||||
if (DECIDERS.size() == 0) DECIDERS.add(decider);
|
||||
else DECIDERS.add(0, decider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new Decider for the {@link BCLibEndBiomeSource}
|
||||
*
|
||||
* @param location The {@link ResourceLocation} for the decider
|
||||
* @param decider The initial decider Instance. Each Instance of the {@link BCLibEndBiomeSource}
|
||||
* will call {@link BiomeDecider#createInstance(BCLBiomeSource)} to build a
|
||||
* new instance of this decider
|
||||
*/
|
||||
public static void registerDecider(ResourceLocation location, BiomeDecider decider) {
|
||||
DECIDERS.add(decider);
|
||||
}
|
||||
|
||||
protected BiomeDecider(BiomePredicate predicate) {
|
||||
this(null, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param biomeRegistry The biome registry assigned to the creating BiomeSource
|
||||
* @param predicate A predicate that decides if a given Biome can be provided by this decider
|
||||
*/
|
||||
protected BiomeDecider(
|
||||
HolderGetter<Biome> biomeRegistry, BiomePredicate predicate
|
||||
) {
|
||||
this.predicate = predicate;
|
||||
this.map = null;
|
||||
if (biomeRegistry == null) {
|
||||
this.picker = null;
|
||||
} else {
|
||||
this.picker = new BiomePicker(biomeRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to test, if a decider is suitable for the given BiomeSource.
|
||||
*
|
||||
* @param source The BiomeSource that wants to use the decider
|
||||
* @return true, if this decider is usable by that source
|
||||
*/
|
||||
public abstract boolean canProvideFor(BiomeSource source);
|
||||
|
||||
/**
|
||||
* Called from the BiomeSource whenever it needs to create a new instance of this decider.
|
||||
* <p>
|
||||
* Inheriting classes should overwrite this method and return Instances of the class. For
|
||||
* the base {@link BiomeDecider} you would return <em>new BiomeDecider(biomeSource.biomeRegistry, this.predicate);</em>
|
||||
*
|
||||
* @param biomeSource The biome source this decider is used from
|
||||
* @return A new instance
|
||||
*/
|
||||
public abstract BiomeDecider createInstance(BCLBiomeSource biomeSource);
|
||||
|
||||
/**
|
||||
* Called when the BiomeSources needs to construct a new {@link BiomeMap} for the picker.
|
||||
* <p>
|
||||
* The default implementation creates a new map with the instances picker and a default biome size
|
||||
*
|
||||
* @param mapBuilder A function you can use to create a new {@link BiomeMap} that conforms to the settings
|
||||
* of the current BiomeSource.
|
||||
*/
|
||||
public void createMap(BiomeMapBuilderFunction mapBuilder) {
|
||||
this.map = mapBuilder.create(picker, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* called whenever the BiomeSource needs to clear caches
|
||||
*/
|
||||
public void clearMapCache() {
|
||||
map.clearCache();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method get's called whenever the BiomeSource populates the Biome Pickers. You need to
|
||||
* determine if the passed Biome is valid for your picker.
|
||||
* <p>
|
||||
* If this method returns false, the Biome wil not get added to any other Deciders/Pickers.
|
||||
* <p>
|
||||
* The default implementation will use the instances {@link BiomeDecider#predicate} to determine if
|
||||
* a biome should get added and return true if it was added.
|
||||
*
|
||||
* @param biome The biome that should get added if it matches the criteria of the picker
|
||||
* @return false, if other pickers/deciders are allowed to use the biome as well
|
||||
*/
|
||||
public boolean addToPicker(BCLBiome biome) {
|
||||
if (predicate.test(biome)) {
|
||||
picker.addBiome(biome);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the picker needs to rebuild it's contents
|
||||
*/
|
||||
public void rebuild() {
|
||||
//TODO: 1.19.3 test if this rebuilds once we have biomes
|
||||
if (picker != null)
|
||||
picker.rebuild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the BiomeSource to determine the type of Biome it needs to place.
|
||||
*
|
||||
* @param originalType The original biome type the source did select
|
||||
* @param suggestedType The currently suggested type. This will differ from <em>originalType</em> if other
|
||||
* {@link BiomeDecider} instances already had a new suggestion. You implementation should return the
|
||||
* <em>suggestedType</em> if it does not want to provide the Biome for this location
|
||||
* @param maxHeight The maximum terrain height for this world
|
||||
* @param blockX The block coordinate where we are at
|
||||
* @param blockY The block coordinate where we are at
|
||||
* @param blockZ The block coordinate where we are at
|
||||
* @param quarterX The quarter Block Coordinate (which is blockX/4)
|
||||
* @param quarterY The quarter Block Coordinate (which is blockY/4)
|
||||
* @param quarterZ The quarter Block Coordinate (which is blockZ/4)
|
||||
* @return The <em>suggestedType</em> if this decider does not plan to provide a Biome, or a unique BiomeType.
|
||||
* The Biome Source will call {@link BiomeDecider#canProvideBiome(BiomeAPI.BiomeType)} with the finally chosen type
|
||||
* for all available Deciders.
|
||||
*/
|
||||
public BiomeAPI.BiomeType suggestType(
|
||||
BiomeAPI.BiomeType originalType,
|
||||
BiomeAPI.BiomeType suggestedType,
|
||||
int maxHeight,
|
||||
int blockX,
|
||||
int blockY,
|
||||
int blockZ,
|
||||
int quarterX,
|
||||
int quarterY,
|
||||
int quarterZ
|
||||
) {
|
||||
return suggestType(
|
||||
originalType,
|
||||
suggestedType,
|
||||
0,
|
||||
maxHeight,
|
||||
blockX,
|
||||
blockY,
|
||||
blockZ,
|
||||
quarterX,
|
||||
quarterY,
|
||||
quarterZ
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from the BiomeSource to determine the type of Biome it needs to place.
|
||||
*
|
||||
* @param originalType The original biome type the source did select
|
||||
* @param suggestedType The currently suggested type. This will differ from <em>originalType</em> if other
|
||||
* {@link BiomeDecider} instances already had a new suggestion. You implementation should return the
|
||||
* <em>suggestedType</em> if it does not want to provide the Biome for this location
|
||||
* @param density The terrain density at this location. Currently only valid if for {@link BCLibEndBiomeSource}
|
||||
* that use the {@link org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig.EndBiomeGeneratorType#VANILLA}
|
||||
* @param maxHeight The maximum terrain height for this world
|
||||
* @param blockX The block coordinate where we are at
|
||||
* @param blockY The block coordinate where we are at
|
||||
* @param blockZ The block coordinate where we are at
|
||||
* @param quarterX The quarter Block Coordinate (which is blockX/4)
|
||||
* @param quarterY The quarter Block Coordinate (which is blockY/4)
|
||||
* @param quarterZ The quarter Block Coordinate (which is blockZ/4)
|
||||
* @param maxHeight
|
||||
* @return The <em>suggestedType</em> if this decider does not plan to provide a Biome, or a unique BiomeType.
|
||||
* The Biome Source will call {@link BiomeDecider#canProvideBiome(BiomeAPI.BiomeType)} with the finally chosen type
|
||||
* for all available Deciders.
|
||||
*/
|
||||
public abstract BiomeAPI.BiomeType suggestType(
|
||||
BiomeAPI.BiomeType originalType,
|
||||
BiomeAPI.BiomeType suggestedType,
|
||||
double density,
|
||||
int maxHeight,
|
||||
int blockX,
|
||||
int blockY,
|
||||
int blockZ,
|
||||
int quarterX,
|
||||
int quarterY,
|
||||
int quarterZ
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* Called to check if this decider can place a biome for the specified type
|
||||
*
|
||||
* @param suggestedType The type of biome we need to place
|
||||
* @return true, if this type of biome can be provided by the current picker. If true
|
||||
* is returned, the BiomeSource will call {@link BiomeDecider#provideBiome(BiomeAPI.BiomeType, int, int, int)}
|
||||
* next
|
||||
*/
|
||||
public abstract boolean canProvideBiome(BiomeAPI.BiomeType suggestedType);
|
||||
|
||||
/**
|
||||
* Called to check if this decider can place a biome for the specified type
|
||||
* <p>
|
||||
* The default implementation will return <em>map.getBiome(posX, posY, posZ)</em>
|
||||
*
|
||||
* @param suggestedType The type of biome we need to place
|
||||
* @return The methode should return a Biome from its {@link BiomeMap}. If null is returned, the next
|
||||
* decider (or the default map) will provide the biome
|
||||
*/
|
||||
public BiomePicker.ActualBiome provideBiome(BiomeAPI.BiomeType suggestedType, int posX, int posY, int posZ) {
|
||||
return map.getBiome(posX, posY, posZ);
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
public enum BiomeType {
|
||||
LAND, VOID
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.config.Configs;
|
||||
|
||||
public class GeneratorOptions {
|
||||
//private static BiFunction<Point, Integer, Boolean> endLandFunction;
|
||||
private static boolean fixEndBiomeSource = true;
|
||||
private static boolean fixNetherBiomeSource = true;
|
||||
|
||||
public static void init() {
|
||||
fixEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixEndBiomeSource", true);
|
||||
fixNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixNetherBiomeSource", true);
|
||||
}
|
||||
|
||||
public static boolean fixEndBiomeSource() {
|
||||
return fixEndBiomeSource;
|
||||
}
|
||||
|
||||
public static boolean fixNetherBiomeSource() {
|
||||
return fixNetherBiomeSource;
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
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 <a href="https://github.com/FabricMC/fabric/pull/2369">this PR</a>
|
||||
*/
|
||||
public class TheEndBiomesHelper {
|
||||
@ApiStatus.Internal
|
||||
private static Map<BiomeAPI.BiomeType, Set<ResourceKey<Biome>>> END_BIOMES = new HashMap<>();
|
||||
|
||||
@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 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 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 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 canGenerateAsEndBarrens(ResourceKey<Biome> biome) {
|
||||
return has(BiomeAPI.BiomeType.END_BARRENS, biome);
|
||||
}
|
||||
|
||||
public static boolean canGenerateInEnd(ResourceKey<Biome> biome) {
|
||||
return canGenerateAsHighlandsBiome(biome)
|
||||
|| canGenerateAsEndBarrens(biome)
|
||||
|| canGenerateAsEndMidlands(biome)
|
||||
|| canGenerateAsSmallIslandsBiome(biome)
|
||||
|| canGenerateAsMainIslandBiome(biome);
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
|
||||
import net.minecraft.core.HolderGetter;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
public abstract class TypeBiomeDecider extends BiomeDecider {
|
||||
protected final BiomeAPI.BiomeType assignedType;
|
||||
|
||||
public TypeBiomeDecider(BiomeAPI.BiomeType assignedType) {
|
||||
this(null, assignedType);
|
||||
}
|
||||
|
||||
protected TypeBiomeDecider(HolderGetter<Biome> biomeRegistry, BiomeAPI.BiomeType assignedType) {
|
||||
super(biomeRegistry, (biome) -> biome.getIntendedType().is(assignedType));
|
||||
this.assignedType = assignedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canProvideBiome(BiomeAPI.BiomeType suggestedType) {
|
||||
return suggestedType.equals(assignedType);
|
||||
}
|
||||
}
|
|
@ -1,268 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.config;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
|
||||
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
|
||||
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;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeSource> {
|
||||
public static final BCLEndBiomeSourceConfig VANILLA = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.VANILLA,
|
||||
EndBiomeGeneratorType.VANILLA,
|
||||
true,
|
||||
4096,
|
||||
128,
|
||||
128,
|
||||
128,
|
||||
128
|
||||
);
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_17 = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.SQUARE,
|
||||
EndBiomeGeneratorType.PAULEVS,
|
||||
true,
|
||||
VANILLA.innerVoidRadiusSquared * 16 * 16,
|
||||
256,
|
||||
256,
|
||||
256,
|
||||
256
|
||||
);
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18 = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
BCLib.RUNS_NULLSCAPE ? EndBiomeGeneratorType.VANILLA : EndBiomeGeneratorType.PAULEVS,
|
||||
BCLib.RUNS_NULLSCAPE ? false : true,
|
||||
MINECRAFT_17.innerVoidRadiusSquared,
|
||||
MINECRAFT_17.centerBiomesSize,
|
||||
MINECRAFT_17.voidBiomesSize,
|
||||
MINECRAFT_17.landBiomesSize,
|
||||
MINECRAFT_17.barrensBiomesSize
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18_LARGE = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
BCLib.RUNS_NULLSCAPE ? EndBiomeGeneratorType.VANILLA : EndBiomeGeneratorType.PAULEVS,
|
||||
BCLib.RUNS_NULLSCAPE ? false : true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize * 2,
|
||||
MINECRAFT_18.landBiomesSize * 4,
|
||||
MINECRAFT_18.barrensBiomesSize * 2
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18_AMPLIFIED = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.PAULEVS,
|
||||
true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize,
|
||||
MINECRAFT_18.landBiomesSize,
|
||||
MINECRAFT_18.barrensBiomesSize
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_20 = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.VANILLA,
|
||||
BCLib.RUNS_NULLSCAPE ? false : true,
|
||||
MINECRAFT_17.innerVoidRadiusSquared,
|
||||
MINECRAFT_17.centerBiomesSize,
|
||||
MINECRAFT_17.voidBiomesSize,
|
||||
MINECRAFT_17.landBiomesSize,
|
||||
MINECRAFT_17.barrensBiomesSize
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_20_LARGE = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.VANILLA,
|
||||
BCLib.RUNS_NULLSCAPE ? false : true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize * 2,
|
||||
MINECRAFT_18.landBiomesSize * 4,
|
||||
MINECRAFT_18.barrensBiomesSize * 2
|
||||
);
|
||||
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_20_AMPLIFIED = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.VANILLA,
|
||||
true,
|
||||
MINECRAFT_18.innerVoidRadiusSquared,
|
||||
MINECRAFT_18.centerBiomesSize,
|
||||
MINECRAFT_18.voidBiomesSize,
|
||||
MINECRAFT_18.landBiomesSize,
|
||||
MINECRAFT_18.barrensBiomesSize
|
||||
);
|
||||
public static final BCLEndBiomeSourceConfig DEFAULT = MINECRAFT_20;
|
||||
|
||||
public static final Codec<BCLEndBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
EndBiomeMapType.CODEC
|
||||
.fieldOf("map_type")
|
||||
.orElse(DEFAULT.mapVersion)
|
||||
.forGetter(o -> o.mapVersion),
|
||||
EndBiomeGeneratorType.CODEC
|
||||
.fieldOf("generator_version")
|
||||
.orElse(DEFAULT.generatorVersion)
|
||||
.forGetter(o -> o.generatorVersion),
|
||||
Codec.BOOL
|
||||
.fieldOf("with_void_biomes")
|
||||
.orElse(DEFAULT.withVoidBiomes)
|
||||
.forGetter(o -> o.withVoidBiomes),
|
||||
Codec.INT
|
||||
.fieldOf("inner_void_radius_squared")
|
||||
.orElse(DEFAULT.innerVoidRadiusSquared)
|
||||
.forGetter(o -> o.innerVoidRadiusSquared),
|
||||
Codec.INT
|
||||
.fieldOf("center_biomes_size")
|
||||
.orElse(DEFAULT.centerBiomesSize)
|
||||
.forGetter(o -> o.centerBiomesSize),
|
||||
Codec.INT
|
||||
.fieldOf("void_biomes_size")
|
||||
.orElse(DEFAULT.voidBiomesSize)
|
||||
.forGetter(o -> o.voidBiomesSize),
|
||||
Codec.INT
|
||||
.fieldOf("land_biomes_size")
|
||||
.orElse(DEFAULT.landBiomesSize)
|
||||
.forGetter(o -> o.landBiomesSize),
|
||||
Codec.INT
|
||||
.fieldOf("barrens_biomes_size")
|
||||
.orElse(DEFAULT.barrensBiomesSize)
|
||||
.forGetter(o -> o.barrensBiomesSize)
|
||||
)
|
||||
.apply(instance, BCLEndBiomeSourceConfig::new));
|
||||
|
||||
public BCLEndBiomeSourceConfig(
|
||||
@NotNull EndBiomeMapType mapVersion,
|
||||
@NotNull EndBiomeGeneratorType generatorVersion,
|
||||
boolean withVoidBiomes,
|
||||
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 {
|
||||
VANILLA("vanilla", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker)),
|
||||
SQUARE("square", (seed, biomeSize, picker) -> new SquareBiomeMap(seed, biomeSize, picker)),
|
||||
HEX("hex", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker));
|
||||
|
||||
public static final Codec<EndBiomeMapType> CODEC = StringRepresentable.fromEnum(EndBiomeMapType::values);
|
||||
public final String name;
|
||||
public final @NotNull MapBuilderFunction mapBuilder;
|
||||
|
||||
EndBiomeMapType(String name, @NotNull MapBuilderFunction mapBuilder) {
|
||||
this.name = name;
|
||||
this.mapBuilder = mapBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
public enum EndBiomeGeneratorType implements StringRepresentable {
|
||||
VANILLA("vanilla"),
|
||||
PAULEVS("paulevs");
|
||||
|
||||
public static final Codec<EndBiomeGeneratorType> CODEC = StringRepresentable.fromEnum(EndBiomeGeneratorType::values);
|
||||
public final String name;
|
||||
|
||||
EndBiomeGeneratorType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final @NotNull EndBiomeMapType mapVersion;
|
||||
public final @NotNull EndBiomeGeneratorType generatorVersion;
|
||||
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 "BCLEndBiomeSourceConfig{" +
|
||||
"mapVersion=" + mapVersion +
|
||||
", generatorVersion=" + generatorVersion +
|
||||
", withVoidBiomes=" + withVoidBiomes +
|
||||
", innerVoidRadiusSquared=" + innerVoidRadiusSquared +
|
||||
", voidBiomesSize=" + voidBiomesSize +
|
||||
", centerBiomesSize=" + centerBiomesSize +
|
||||
", landBiomesSize=" + landBiomesSize +
|
||||
", barrensBiomesSize=" + barrensBiomesSize +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean couldSetWithoutRepair(BiomeSourceConfig<?> input) {
|
||||
if (input instanceof BCLEndBiomeSourceConfig cfg) {
|
||||
return withVoidBiomes == cfg.withVoidBiomes && mapVersion == cfg.mapVersion && generatorVersion == cfg.generatorVersion;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameConfig(BiomeSourceConfig<?> input) {
|
||||
return this.equals(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BCLEndBiomeSourceConfig that = (BCLEndBiomeSourceConfig) o;
|
||||
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,
|
||||
voidBiomesSize,
|
||||
centerBiomesSize,
|
||||
landBiomesSize,
|
||||
barrensBiomesSize
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,157 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.config;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
|
||||
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
|
||||
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;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNetherBiomeSource> {
|
||||
public static final BCLNetherBiomeSourceConfig VANILLA = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.VANILLA,
|
||||
256,
|
||||
86,
|
||||
false,
|
||||
false
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_17 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.SQUARE,
|
||||
256,
|
||||
86,
|
||||
true,
|
||||
false
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_17.biomeSize,
|
||||
MINECRAFT_17.biomeSizeVertical,
|
||||
MINECRAFT_17.useVerticalBiomes,
|
||||
MINECRAFT_17.amplified
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18_LARGE = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_18.biomeSize * 4,
|
||||
MINECRAFT_18.biomeSizeVertical * 2,
|
||||
MINECRAFT_18.useVerticalBiomes,
|
||||
MINECRAFT_17.amplified
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18_AMPLIFIED = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_18.biomeSize,
|
||||
128,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
public static final BCLNetherBiomeSourceConfig DEFAULT = MINECRAFT_18;
|
||||
|
||||
public static final Codec<BCLNetherBiomeSourceConfig> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
BCLNetherBiomeSourceConfig.NetherBiomeMapType.CODEC
|
||||
.fieldOf("map_type")
|
||||
.orElse(DEFAULT.mapVersion)
|
||||
.forGetter(o -> o.mapVersion),
|
||||
Codec.INT.fieldOf("biome_size").orElse(DEFAULT.biomeSize).forGetter(o -> o.biomeSize),
|
||||
Codec.INT.fieldOf("biome_size_vertical")
|
||||
.orElse(DEFAULT.biomeSizeVertical)
|
||||
.forGetter(o -> o.biomeSizeVertical),
|
||||
Codec.BOOL.fieldOf("use_vertical_biomes")
|
||||
.orElse(DEFAULT.useVerticalBiomes)
|
||||
.forGetter(o -> o.useVerticalBiomes),
|
||||
Codec.BOOL.fieldOf("amplified")
|
||||
.orElse(DEFAULT.amplified)
|
||||
.forGetter(o -> o.amplified)
|
||||
)
|
||||
.apply(instance, BCLNetherBiomeSourceConfig::new));
|
||||
public final @NotNull NetherBiomeMapType mapVersion;
|
||||
public final int biomeSize;
|
||||
public final int biomeSizeVertical;
|
||||
|
||||
public final boolean useVerticalBiomes;
|
||||
public final boolean amplified;
|
||||
|
||||
public BCLNetherBiomeSourceConfig(
|
||||
@NotNull NetherBiomeMapType mapVersion,
|
||||
int biomeSize,
|
||||
int biomeSizeVertical,
|
||||
boolean useVerticalBiomes,
|
||||
boolean amplified
|
||||
) {
|
||||
this.mapVersion = mapVersion;
|
||||
this.biomeSize = Mth.clamp(biomeSize, 1, 8192);
|
||||
this.biomeSizeVertical = Mth.clamp(biomeSizeVertical, 1, 8192);
|
||||
this.useVerticalBiomes = useVerticalBiomes;
|
||||
this.amplified = amplified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BCLibNetherBiomeSourceConfig{" +
|
||||
"mapVersion=" + mapVersion +
|
||||
", useVerticalBiomes=" + useVerticalBiomes +
|
||||
", amplified=" + amplified +
|
||||
", biomeSize=" + biomeSize +
|
||||
", biomeSizeVertical=" + biomeSizeVertical +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean couldSetWithoutRepair(BiomeSourceConfig<?> input) {
|
||||
if (input instanceof BCLNetherBiomeSourceConfig cfg) {
|
||||
return mapVersion == cfg.mapVersion;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sameConfig(BiomeSourceConfig<?> input) {
|
||||
return this.equals(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof BCLNetherBiomeSourceConfig)) return false;
|
||||
BCLNetherBiomeSourceConfig that = (BCLNetherBiomeSourceConfig) o;
|
||||
return mapVersion == that.mapVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mapVersion);
|
||||
}
|
||||
|
||||
public enum NetherBiomeMapType implements StringRepresentable {
|
||||
VANILLA("vanilla", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker)),
|
||||
SQUARE("square", (seed, biomeSize, picker) -> new SquareBiomeMap(seed, biomeSize, picker)),
|
||||
HEX("hex", (seed, biomeSize, picker) -> new HexBiomeMap(seed, biomeSize, picker));
|
||||
|
||||
public static final Codec<NetherBiomeMapType> CODEC = StringRepresentable.fromEnum(NetherBiomeMapType::values);
|
||||
public final String name;
|
||||
public final MapBuilderFunction mapBuilder;
|
||||
|
||||
NetherBiomeMapType(String name, MapBuilderFunction mapBuilder) {
|
||||
this.name = name;
|
||||
this.mapBuilder = mapBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.config;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface MapBuilderFunction {
|
||||
BiomeMap create(long seed, int biomeSize, BiomePicker picker);
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.map;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.api.v2.generator.config.MapBuilderFunction;
|
||||
import org.betterx.bclib.interfaces.BiomeChunk;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.bclib.interfaces.TriConsumer;
|
||||
import org.betterx.bclib.noise.OpenSimplexNoise;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class MapStack implements BiomeMap {
|
||||
private final OpenSimplexNoise noise;
|
||||
private final BiomeMap[] maps;
|
||||
private final double layerDistortion;
|
||||
private final int worldHeight;
|
||||
private final int minValue;
|
||||
private final int maxValue;
|
||||
private final int maxIndex;
|
||||
|
||||
public MapStack(
|
||||
long seed,
|
||||
int size,
|
||||
BiomePicker picker,
|
||||
int mapHeight,
|
||||
int worldHeight,
|
||||
MapBuilderFunction mapConstructor
|
||||
) {
|
||||
final int mapCount = Mth.ceil((float) worldHeight / mapHeight);
|
||||
this.maxIndex = mapCount - 1;
|
||||
this.worldHeight = worldHeight;
|
||||
this.layerDistortion = mapHeight * 0.1;
|
||||
minValue = Mth.floor(mapHeight * 0.5F + 0.5F);
|
||||
maxValue = Mth.floor(worldHeight - mapHeight * 0.5F + 0.5F);
|
||||
maps = new BiomeMap[mapCount];
|
||||
Random random = new Random(seed);
|
||||
for (int i = 0; i < mapCount; i++) {
|
||||
maps[i] = mapConstructor.create(random.nextLong(), size, picker);
|
||||
maps[i].setChunkProcessor(this::onChunkCreation);
|
||||
}
|
||||
noise = new OpenSimplexNoise(random.nextInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
for (BiomeMap map : maps) {
|
||||
map.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunkProcessor(TriConsumer<Integer, Integer, Integer> processor) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeChunk getChunk(int cx, int cz, boolean update) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomePicker.ActualBiome getBiome(double x, double y, double z) {
|
||||
int mapIndex;
|
||||
|
||||
if (y < minValue) {
|
||||
mapIndex = 0;
|
||||
} else if (y > maxValue) {
|
||||
mapIndex = maxIndex;
|
||||
} else {
|
||||
mapIndex = Mth.floor((y + noise.eval(
|
||||
x * 0.03,
|
||||
z * 0.03
|
||||
) * layerDistortion) / worldHeight * maxIndex + 0.5F);
|
||||
mapIndex = Mth.clamp(mapIndex, 0, maxIndex);
|
||||
}
|
||||
|
||||
return maps[mapIndex].getBiome(x, y, z);
|
||||
}
|
||||
|
||||
private void onChunkCreation(int cx, int cz, int side) {
|
||||
BiomePicker.ActualBiome[][] biomeMap = new BiomePicker.ActualBiome[side][side];
|
||||
BiomeChunk[] chunks = new BiomeChunk[maps.length];
|
||||
|
||||
boolean isNoEmpty = false;
|
||||
for (int i = 0; i < maps.length; i++) {
|
||||
chunks[i] = maps[i].getChunk(cx, cz, false);
|
||||
for (int x = 0; x < side; x++) {
|
||||
for (int z = 0; z < side; z++) {
|
||||
if (biomeMap[x][z] == null) {
|
||||
BiomePicker.ActualBiome biome = chunks[i].getBiome(x, z);
|
||||
if (biome == null) {
|
||||
biome = chunks[i].getBiome(x, z);
|
||||
}
|
||||
if (biome.bclBiome.settings.isVertical()) {
|
||||
biomeMap[x][z] = biome;
|
||||
isNoEmpty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isNoEmpty) {
|
||||
for (int i = 0; i < maps.length; i++) {
|
||||
for (int x = 0; x < side; x++) {
|
||||
for (int z = 0; z < side; z++) {
|
||||
if (biomeMap[x][z] != null) {
|
||||
chunks[i].setBiome(x, z, biomeMap[x][z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.map.hex;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.interfaces.BiomeChunk;
|
||||
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class HexBiomeChunk implements BiomeChunk {
|
||||
private static final short SIDE = 32;
|
||||
private static final byte SIDE_PRE = 4;
|
||||
private static final short SIZE = SIDE * SIDE;
|
||||
private static final short MAX_SIDE = SIZE - SIDE;
|
||||
private static final byte SCALE_PRE = SIDE / SIDE_PRE;
|
||||
private static final byte SIZE_PRE = SIDE_PRE * SIDE_PRE;
|
||||
private static final byte SIDE_MASK = SIDE - 1;
|
||||
private static final byte SIDE_PRE_MASK = SIDE_PRE - 1;
|
||||
private static final byte SIDE_OFFSET = (byte) Math.round(Math.log(SIDE) / Math.log(2));
|
||||
private static final byte SIDE_PRE_OFFSET = (byte) Math.round(Math.log(SIDE_PRE) / Math.log(2));
|
||||
private static final short[][] NEIGHBOURS;
|
||||
|
||||
private final BiomePicker.ActualBiome[] biomes = new BiomePicker.ActualBiome[SIZE];
|
||||
|
||||
public HexBiomeChunk(WorldgenRandom random, BiomePicker picker) {
|
||||
BiomePicker.ActualBiome[][] buffers = new BiomePicker.ActualBiome[2][SIZE];
|
||||
|
||||
for (BiomePicker.ActualBiome[] buffer : buffers) {
|
||||
Arrays.fill(buffer, null);
|
||||
}
|
||||
|
||||
for (byte index = 0; index < SIZE_PRE; index++) {
|
||||
byte px = (byte) (index >> SIDE_PRE_OFFSET);
|
||||
byte pz = (byte) (index & SIDE_PRE_MASK);
|
||||
px = (byte) (px * SCALE_PRE + random.nextInt(SCALE_PRE));
|
||||
pz = (byte) (pz * SCALE_PRE + random.nextInt(SCALE_PRE));
|
||||
circle(buffers[0], getIndex(px, pz), picker.getBiome(random), null);
|
||||
}
|
||||
|
||||
boolean hasEmptyCells = true;
|
||||
byte bufferIndex = 0;
|
||||
while (hasEmptyCells) {
|
||||
BiomePicker.ActualBiome[] inBuffer = buffers[bufferIndex];
|
||||
bufferIndex = (byte) ((bufferIndex + 1) & 1);
|
||||
BiomePicker.ActualBiome[] outBuffer = buffers[bufferIndex];
|
||||
hasEmptyCells = false;
|
||||
|
||||
for (short index = SIDE; index < MAX_SIDE; index++) {
|
||||
byte z = (byte) (index & SIDE_MASK);
|
||||
if (z == 0 || z == SIDE_MASK) {
|
||||
continue;
|
||||
}
|
||||
if (inBuffer[index] != null) {
|
||||
outBuffer[index] = inBuffer[index];
|
||||
short[] neighbours = getNeighbours(index & SIDE_MASK);
|
||||
short indexSide = (short) (index + neighbours[random.nextInt(6)]);
|
||||
if (indexSide >= 0 && indexSide < SIZE && outBuffer[indexSide] == null) {
|
||||
outBuffer[indexSide] = inBuffer[index];
|
||||
}
|
||||
} else {
|
||||
hasEmptyCells = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BiomePicker.ActualBiome[] outBuffer = buffers[bufferIndex];
|
||||
byte preN = (byte) (SIDE_MASK - 2);
|
||||
for (byte index = 0; index < SIDE; index++) {
|
||||
outBuffer[getIndex(index, (byte) 0)] = outBuffer[getIndex(index, (byte) 2)];
|
||||
outBuffer[getIndex((byte) 0, index)] = outBuffer[getIndex((byte) 2, index)];
|
||||
outBuffer[getIndex(index, SIDE_MASK)] = outBuffer[getIndex(index, preN)];
|
||||
outBuffer[getIndex(SIDE_MASK, index)] = outBuffer[getIndex(preN, index)];
|
||||
}
|
||||
|
||||
int lastAction = -1;
|
||||
BiomePicker.ActualBiome lBiome = null;
|
||||
for (short index = 0; index < SIZE; index++) {
|
||||
if (outBuffer[index] == null) {
|
||||
lastAction = 0;
|
||||
lBiome = null;
|
||||
outBuffer[index] = picker.getBiome(random);
|
||||
} else if (random.nextInt(4) == 0) {
|
||||
lastAction = 1;
|
||||
lBiome = outBuffer[index];
|
||||
circle(outBuffer, index, outBuffer[index].getSubBiome(random), outBuffer[index]);
|
||||
}
|
||||
|
||||
if (outBuffer[index] == null) {
|
||||
BCLib.LOGGER.error("Invalid Biome at " + index + ", " + lastAction + ", " + lBiome);
|
||||
}
|
||||
}
|
||||
|
||||
System.arraycopy(outBuffer, 0, this.biomes, 0, SIZE);
|
||||
}
|
||||
|
||||
private void circle(
|
||||
BiomePicker.ActualBiome[] buffer,
|
||||
short center,
|
||||
BiomePicker.ActualBiome biome,
|
||||
BiomePicker.ActualBiome mask
|
||||
) {
|
||||
if (buffer[center] == mask) {
|
||||
buffer[center] = biome;
|
||||
}
|
||||
short[] neighbours = getNeighbours(center & SIDE_MASK);
|
||||
for (short i : neighbours) {
|
||||
short index = (short) (center + i);
|
||||
if (index >= 0 && index < SIZE && buffer[index] == mask) {
|
||||
buffer[index] = biome;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static byte wrap(int value) {
|
||||
return (byte) (value & SIDE_MASK);
|
||||
}
|
||||
|
||||
private short getIndex(byte x, byte z) {
|
||||
return (short) ((short) x << SIDE_OFFSET | z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomePicker.ActualBiome getBiome(int x, int z) {
|
||||
return biomes[getIndex(wrap(x), wrap(z))];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, BiomePicker.ActualBiome biome) {
|
||||
biomes[getIndex(wrap(x), wrap(z))] = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSide() {
|
||||
return SIDE;
|
||||
}
|
||||
|
||||
public static int scaleCoordinate(int value) {
|
||||
return value >> SIDE_OFFSET;
|
||||
}
|
||||
|
||||
public static boolean isBorder(int value) {
|
||||
return wrap(value) == SIDE_MASK;
|
||||
}
|
||||
|
||||
private short[] getNeighbours(int z) {
|
||||
return NEIGHBOURS[z & 1];
|
||||
}
|
||||
|
||||
public static float scaleMap(float size) {
|
||||
return size / (SIDE >> 2);
|
||||
}
|
||||
|
||||
static {
|
||||
NEIGHBOURS = new short[2][6];
|
||||
|
||||
NEIGHBOURS[0][0] = 1;
|
||||
NEIGHBOURS[0][1] = -1;
|
||||
NEIGHBOURS[0][2] = SIDE;
|
||||
NEIGHBOURS[0][3] = -SIDE;
|
||||
NEIGHBOURS[0][4] = SIDE + 1;
|
||||
NEIGHBOURS[0][5] = SIDE - 1;
|
||||
|
||||
NEIGHBOURS[1][0] = 1;
|
||||
NEIGHBOURS[1][1] = -1;
|
||||
NEIGHBOURS[1][2] = SIDE;
|
||||
NEIGHBOURS[1][3] = -SIDE;
|
||||
NEIGHBOURS[1][4] = -SIDE + 1;
|
||||
NEIGHBOURS[1][5] = -SIDE - 1;
|
||||
}
|
||||
}
|
|
@ -1,187 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.map.hex;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.interfaces.BiomeChunk;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.bclib.interfaces.TriConsumer;
|
||||
import org.betterx.bclib.noise.OpenSimplexNoise;
|
||||
import org.betterx.bclib.util.MHelper;
|
||||
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class HexBiomeMap implements BiomeMap {
|
||||
private static final float RAD_INNER = (float) Math.sqrt(3.0) * 0.5F;
|
||||
private static final float COEF = 0.25F * (float) Math.sqrt(3.0);
|
||||
private static final float COEF_HALF = COEF * 0.5F;
|
||||
private static final float SIN = (float) Math.sin(0.4);
|
||||
private static final float COS = (float) Math.cos(0.4);
|
||||
private static final float[] EDGE_CIRCLE_X;
|
||||
private static final float[] EDGE_CIRCLE_Z;
|
||||
|
||||
private final Map<ChunkPos, HexBiomeChunk> chunks = Maps.newConcurrentMap();
|
||||
private final BiomePicker picker;
|
||||
|
||||
private final OpenSimplexNoise[] noises = new OpenSimplexNoise[2];
|
||||
private TriConsumer<Integer, Integer, Integer> processor;
|
||||
private final byte noiseIterations;
|
||||
private final float scale;
|
||||
private final int seed;
|
||||
|
||||
public HexBiomeMap(long seed, int size, BiomePicker picker) {
|
||||
this.picker = picker;
|
||||
this.scale = HexBiomeChunk.scaleMap(size);
|
||||
Random random = new Random(seed);
|
||||
|
||||
noises[0] = new OpenSimplexNoise(random.nextInt());
|
||||
noises[1] = new OpenSimplexNoise(random.nextInt());
|
||||
noiseIterations = (byte) Math.min(Math.ceil(Math.log(scale) / Math.log(2)), 5);
|
||||
this.seed = random.nextInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
if (chunks.size() > 127) {
|
||||
chunks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomePicker.ActualBiome getBiome(double x, double y, double z) {
|
||||
BiomePicker.ActualBiome biome = getRawBiome(x, z);
|
||||
BiomePicker.ActualBiome edge = biome.getEdge();
|
||||
int size = biome.bclBiome.settings.getEdgeSize();
|
||||
|
||||
if (edge == null && biome.getParentBiome() != null) {
|
||||
edge = biome.getParentBiome().getEdge();
|
||||
size = biome.getParentBiome().bclBiome.settings.getEdgeSize();
|
||||
}
|
||||
|
||||
if (edge == null) {
|
||||
return biome;
|
||||
}
|
||||
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
if (!getRawBiome(x + size * EDGE_CIRCLE_X[i], z + size * EDGE_CIRCLE_Z[i]).isSame(biome)) {
|
||||
return edge;
|
||||
}
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeChunk getChunk(final int cx, final int cz, final boolean update) {
|
||||
final ChunkPos pos = new ChunkPos(cx, cz);
|
||||
HexBiomeChunk chunk = chunks.get(pos);
|
||||
if (chunk == null) {
|
||||
WorldgenRandom random = new WorldgenRandom(RandomSource.create(MHelper.getSeed(seed, cx, cz)));
|
||||
chunk = new HexBiomeChunk(random, picker);
|
||||
if (update && processor != null) {
|
||||
processor.accept(cx, cz, chunk.getSide());
|
||||
}
|
||||
chunks.put(pos, chunk);
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunkProcessor(TriConsumer<Integer, Integer, Integer> processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
private BiomePicker.ActualBiome getRawBiome(double x, double z) {
|
||||
double px = x / scale * RAD_INNER;
|
||||
double pz = z / scale;
|
||||
double dx = rotateX(px, pz);
|
||||
double dz = rotateZ(px, pz);
|
||||
px = dx;
|
||||
pz = dz;
|
||||
|
||||
dx = getNoise(px, pz, (byte) 0) * 0.2F;
|
||||
dz = getNoise(pz, px, (byte) 1) * 0.2F;
|
||||
px += dx;
|
||||
pz += dz;
|
||||
|
||||
int cellZ = (int) Math.floor(pz);
|
||||
boolean offset = (cellZ & 1) == 1;
|
||||
|
||||
if (offset) {
|
||||
px += 0.5;
|
||||
}
|
||||
|
||||
int cellX = (int) Math.floor(px);
|
||||
|
||||
float pointX = (float) (px - cellX - 0.5);
|
||||
float pointZ = (float) (pz - cellZ - 0.5);
|
||||
|
||||
if (Math.abs(pointZ) < 0.3333F) {
|
||||
return getChunkBiome(cellX, cellZ);
|
||||
}
|
||||
|
||||
if (insideHexagon(0, 0, 1.1555F, pointZ * RAD_INNER, pointX)) {
|
||||
return getChunkBiome(cellX, cellZ);
|
||||
}
|
||||
|
||||
cellX = pointX < 0 ? (offset ? cellX - 1 : cellX) : (offset ? cellX : cellX + 1);
|
||||
cellZ = pointZ < 0 ? cellZ - 1 : cellZ + 1;
|
||||
|
||||
return getChunkBiome(cellX, cellZ);
|
||||
}
|
||||
|
||||
private BiomePicker.ActualBiome getChunkBiome(int x, int z) {
|
||||
int cx = HexBiomeChunk.scaleCoordinate(x);
|
||||
int cz = HexBiomeChunk.scaleCoordinate(z);
|
||||
|
||||
if (((z >> 2) & 1) == 0 && HexBiomeChunk.isBorder(x)) {
|
||||
x = 0;
|
||||
cx += 1;
|
||||
} else if (((x >> 2) & 1) == 0 && HexBiomeChunk.isBorder(z)) {
|
||||
z = 0;
|
||||
cz += 1;
|
||||
}
|
||||
|
||||
return getChunk(cx, cz, true).getBiome(x, z);
|
||||
}
|
||||
|
||||
private boolean insideHexagon(float centerX, float centerZ, float radius, float x, float z) {
|
||||
double dx = Math.abs(x - centerX) / radius;
|
||||
double dy = Math.abs(z - centerZ) / radius;
|
||||
return (dy <= COEF) && (COEF * dx + 0.25F * dy <= COEF_HALF);
|
||||
}
|
||||
|
||||
private double getNoise(double x, double z, byte state) {
|
||||
double result = 0;
|
||||
for (byte i = 1; i <= noiseIterations; i++) {
|
||||
OpenSimplexNoise noise = noises[state];
|
||||
state = (byte) ((state + 1) & 1);
|
||||
result += noise.eval(x * i, z * i) / i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private double rotateX(double x, double z) {
|
||||
return x * COS - z * SIN;
|
||||
}
|
||||
|
||||
private double rotateZ(double x, double z) {
|
||||
return x * SIN + z * COS;
|
||||
}
|
||||
|
||||
static {
|
||||
EDGE_CIRCLE_X = new float[8];
|
||||
EDGE_CIRCLE_Z = new float[8];
|
||||
|
||||
for (byte i = 0; i < 8; i++) {
|
||||
float angle = i / 4F * (float) Math.PI;
|
||||
EDGE_CIRCLE_X[i] = (float) Math.sin(angle);
|
||||
EDGE_CIRCLE_Z[i] = (float) Math.cos(angle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.map.square;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.interfaces.BiomeChunk;
|
||||
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
public class SquareBiomeChunk implements BiomeChunk {
|
||||
private static final int BIT_OFFSET = 4;
|
||||
protected static final int WIDTH = 1 << BIT_OFFSET;
|
||||
private static final int SM_WIDTH = WIDTH >> 1;
|
||||
private static final int SM_BIT_OFFSET = BIT_OFFSET >> 1;
|
||||
private static final int MASK_OFFSET = SM_WIDTH - 1;
|
||||
protected static final int MASK_WIDTH = WIDTH - 1;
|
||||
|
||||
private static final int SM_CAPACITY = SM_WIDTH * SM_WIDTH;
|
||||
private static final int CAPACITY = WIDTH * WIDTH;
|
||||
|
||||
private final BiomePicker.ActualBiome[] biomes;
|
||||
|
||||
public SquareBiomeChunk(WorldgenRandom random, BiomePicker picker) {
|
||||
BiomePicker.ActualBiome[] PreBio = new BiomePicker.ActualBiome[SM_CAPACITY];
|
||||
biomes = new BiomePicker.ActualBiome[CAPACITY];
|
||||
|
||||
for (int x = 0; x < SM_WIDTH; x++) {
|
||||
int offset = x << SM_BIT_OFFSET;
|
||||
for (int z = 0; z < SM_WIDTH; z++) {
|
||||
PreBio[offset | z] = picker.getBiome(random);
|
||||
}
|
||||
}
|
||||
|
||||
for (int x = 0; x < WIDTH; x++) {
|
||||
int offset = x << BIT_OFFSET;
|
||||
for (int z = 0; z < WIDTH; z++) {
|
||||
biomes[offset | z] = PreBio[getSmIndex(offsetXZ(x, random), offsetXZ(z, random))].getSubBiome(random);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomePicker.ActualBiome getBiome(int x, int z) {
|
||||
return biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, BiomePicker.ActualBiome biome) {
|
||||
biomes[getIndex(x & MASK_WIDTH, z & MASK_WIDTH)] = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSide() {
|
||||
return WIDTH;
|
||||
}
|
||||
|
||||
private int offsetXZ(int x, WorldgenRandom random) {
|
||||
return ((x + random.nextInt(2)) >> 1) & MASK_OFFSET;
|
||||
}
|
||||
|
||||
private int getIndex(int x, int z) {
|
||||
return x << BIT_OFFSET | z;
|
||||
}
|
||||
|
||||
private int getSmIndex(int x, int z) {
|
||||
return x << SM_BIT_OFFSET | z;
|
||||
}
|
||||
}
|
|
@ -1,143 +0,0 @@
|
|||
package org.betterx.bclib.api.v2.generator.map.square;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.interfaces.BiomeChunk;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.bclib.interfaces.TriConsumer;
|
||||
import org.betterx.bclib.noise.OpenSimplexNoise;
|
||||
import org.betterx.bclib.util.MHelper;
|
||||
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class SquareBiomeMap implements BiomeMap {
|
||||
private final Map<ChunkPos, SquareBiomeChunk> maps = Maps.newHashMap();
|
||||
private final OpenSimplexNoise noiseX;
|
||||
private final OpenSimplexNoise noiseZ;
|
||||
private final WorldgenRandom random;
|
||||
private final BiomePicker picker;
|
||||
|
||||
private final int sizeXZ;
|
||||
private final int depth;
|
||||
private final int size;
|
||||
|
||||
private TriConsumer<Integer, Integer, Integer> processor;
|
||||
|
||||
public SquareBiomeMap(long seed, int size, BiomePicker picker) {
|
||||
random = new WorldgenRandom(new LegacyRandomSource(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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
if (maps.size() > 32) {
|
||||
maps.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomePicker.ActualBiome getBiome(double x, double y, double z) {
|
||||
BiomePicker.ActualBiome biome = getRawBiome(x, z);
|
||||
|
||||
if (biome.getEdge() != null || (biome.getParentBiome() != null && biome.getParentBiome().getEdge() != null)) {
|
||||
BiomePicker.ActualBiome search = biome;
|
||||
if (biome.getParentBiome() != null) {
|
||||
search = biome.getParentBiome();
|
||||
}
|
||||
|
||||
int size = search.bclBiome.settings.getEdgeSize();
|
||||
boolean edge = !search.isSame(getRawBiome(x + size, z));
|
||||
edge = edge || !search.isSame(getRawBiome(x - size, z));
|
||||
edge = edge || !search.isSame(getRawBiome(x, z + size));
|
||||
edge = edge || !search.isSame(getRawBiome(x, z - size));
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunkProcessor(TriConsumer<Integer, Integer, Integer> processor) {
|
||||
this.processor = processor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiomeChunk getChunk(int cx, int cz, boolean update) {
|
||||
ChunkPos cpos = new ChunkPos(cx, cz);
|
||||
SquareBiomeChunk chunk = maps.get(cpos);
|
||||
if (chunk == null) {
|
||||
synchronized (random) {
|
||||
random.setLargeFeatureWithSalt(0, cpos.x, cpos.z, 0);
|
||||
chunk = new SquareBiomeChunk(random, picker);
|
||||
}
|
||||
maps.put(cpos, chunk);
|
||||
|
||||
if (update && processor != null) {
|
||||
processor.accept(cx, cz, chunk.getSide());
|
||||
}
|
||||
}
|
||||
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private BiomePicker.ActualBiome getRawBiome(double bx, double bz) {
|
||||
double x = bx * size / sizeXZ;
|
||||
double z = bz * size / sizeXZ;
|
||||
|
||||
double px = bx * 0.2;
|
||||
double pz = bz * 0.2;
|
||||
|
||||
for (int i = 0; i < depth; i++) {
|
||||
double nx = (x + noiseX.eval(px, pz)) / 2F;
|
||||
double nz = (z + noiseZ.eval(px, pz)) / 2F;
|
||||
|
||||
x = nx;
|
||||
z = nz;
|
||||
|
||||
px = px / 2 + i;
|
||||
pz = pz / 2 + i;
|
||||
}
|
||||
|
||||
int ix = MHelper.floor(x);
|
||||
int iz = MHelper.floor(z);
|
||||
|
||||
if ((ix & SquareBiomeChunk.MASK_WIDTH) == SquareBiomeChunk.MASK_WIDTH) {
|
||||
x += (iz / 2) & 1;
|
||||
}
|
||||
if ((iz & SquareBiomeChunk.MASK_WIDTH) == SquareBiomeChunk.MASK_WIDTH) {
|
||||
z += (ix / 2) & 1;
|
||||
}
|
||||
|
||||
ChunkPos cpos = new ChunkPos(
|
||||
MHelper.floor(x / SquareBiomeChunk.WIDTH),
|
||||
MHelper.floor(z / SquareBiomeChunk.WIDTH)
|
||||
);
|
||||
SquareBiomeChunk chunk = maps.get(cpos);
|
||||
if (chunk == null) {
|
||||
synchronized (random) {
|
||||
random.setLargeFeatureWithSalt(0, cpos.x, cpos.z, 0);
|
||||
chunk = new SquareBiomeChunk(random, picker);
|
||||
}
|
||||
maps.put(cpos, chunk);
|
||||
}
|
||||
|
||||
return chunk.getBiome(MHelper.floor(x), MHelper.floor(z));
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -29,7 +29,6 @@
|
|||
"ServerLevelMixin",
|
||||
"ShovelItemAccessor",
|
||||
"SurfaceRulesContextAccessor",
|
||||
"TheEndBiomesMixin",
|
||||
"WorldGenRegionMixin",
|
||||
"boat.BoatItemMixin",
|
||||
"boat.BoatMixin",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue