Merge branch '1.19' into 1.18.2-backported
# Conflicts: # src/main/java/org/betterx/bclib/api/v2/levelgen/biomes/BiomeAPI.java # src/main/java/org/betterx/bclib/api/v2/levelgen/structures/TemplatePiece.java # src/main/java/org/betterx/bclib/api/v3/levelgen/features/features/TemplateFeature.java # src/main/java/org/betterx/bclib/commands/DumpDatapack.java # src/main/java/org/betterx/bclib/util/MHelper.java # src/main/java/org/betterx/bclib/util/WeightedList.java # src/main/java/org/betterx/worlds/together/levelgen/WorldGenUtil.java # src/main/java/org/betterx/worlds/together/mixin/common/WorldGenPropertiesMixin.java # src/main/java/org/betterx/worlds/together/tag/v3/TagRegistry.java # src/main/java/org/betterx/worlds/together/worldPreset/client/WorldPresetsClient.java # src/main/resources/bclib.accesswidener
This commit is contained in:
commit
cee6f167c7
81 changed files with 3162 additions and 799 deletions
|
@ -8,7 +8,7 @@ minecraft_version=1.18.2
|
|||
loader_version=0.14.8
|
||||
fabric_version=0.57.0+1.19
|
||||
# Mod Properties
|
||||
mod_version=2.0.8
|
||||
mod_version=2.0.11
|
||||
maven_group=org.betterx.bclib
|
||||
archives_base_name=bclib
|
||||
# Dependencies
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.betterx.bclib.api.v2.generator.GeneratorOptions;
|
|||
import org.betterx.bclib.api.v2.levelgen.LevelGenEvents;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeBuilder;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.api.v2.levelgen.structures.TemplatePiece;
|
||||
import org.betterx.bclib.api.v2.levelgen.surface.rules.Conditions;
|
||||
|
@ -19,9 +20,9 @@ import org.betterx.bclib.recipes.AnvilRecipe;
|
|||
import org.betterx.bclib.recipes.CraftingRecipes;
|
||||
import org.betterx.bclib.registry.BaseBlockEntities;
|
||||
import org.betterx.bclib.registry.BaseRegistry;
|
||||
import org.betterx.bclib.util.Logger;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
import org.betterx.worlds.together.util.Logger;
|
||||
import org.betterx.worlds.together.world.WorldConfig;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
@ -38,11 +39,15 @@ public class BCLib implements ModInitializer {
|
|||
public static final String MOD_ID = "bclib";
|
||||
public static final Logger LOGGER = new Logger(MOD_ID);
|
||||
|
||||
public static final boolean RUNS_NULLSCAPE = FabricLoader.getInstance()
|
||||
.getModContainer("nullscape")
|
||||
.isPresent();
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
LevelGenEvents.register();
|
||||
WorldsTogether.onInitialize();
|
||||
BlockPredicates.ensureStaticInitialization();
|
||||
BCLBiomeRegistry.ensureStaticallyLoaded();
|
||||
BaseRegistry.register();
|
||||
GeneratorOptions.init();
|
||||
BaseBlockEntities.register();
|
||||
|
@ -70,6 +75,8 @@ public class BCLib implements ModInitializer {
|
|||
PlacementModifiers.ensureStaticInitialization();
|
||||
Configs.save();
|
||||
|
||||
WorldsTogether.FORCE_SERVER_TO_BETTERX_PRESET = Configs.SERVER_CONFIG.forceBetterXPreset();
|
||||
|
||||
if (false && isDevEnvironment()) {
|
||||
BCLBiome theYellow = BCLBiomeBuilder
|
||||
.start(makeID("the_yellow"))
|
||||
|
|
|
@ -7,7 +7,7 @@ import org.betterx.bclib.client.gui.screens.LevelFixErrorScreen;
|
|||
import org.betterx.bclib.client.gui.screens.LevelFixErrorScreen.Listener;
|
||||
import org.betterx.bclib.client.gui.screens.ProgressScreen;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.util.Logger;
|
||||
import org.betterx.worlds.together.util.Logger;
|
||||
import org.betterx.worlds.together.world.WorldConfig;
|
||||
|
||||
import net.minecraft.Util;
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceFromRegistry;
|
||||
import org.betterx.worlds.together.biomesource.MergeableBiomeSource;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithSeed;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
|
@ -9,6 +11,7 @@ import net.minecraft.core.Registry;
|
|||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
|
@ -16,7 +19,7 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource<BCLBiomeSource> {
|
||||
public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceWithSeed, MergeableBiomeSource<BCLBiomeSource>, BiomeSourceWithNoiseRelatedSettings, BiomeSourceFromRegistry {
|
||||
protected final Registry<Biome> biomeRegistry;
|
||||
protected long currentSeed;
|
||||
protected int maxHeight;
|
||||
|
@ -110,4 +113,12 @@ public abstract class BCLBiomeSource extends BiomeSource implements BiomeSourceW
|
|||
final Set<Holder<Biome>> datapackBiomes = inputBiomeSource.possibleBiomes();
|
||||
return this.createCopyForDatapack(datapackBiomes);
|
||||
}
|
||||
|
||||
public void onLoadGeneratorSettings(NoiseGeneratorSettings generator) {
|
||||
this.setMaxHeight(generator.noiseSettings().height());
|
||||
}
|
||||
|
||||
public Registry<Biome> getBiomeRegistry() {
|
||||
return biomeRegistry;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,11 @@ import org.betterx.bclib.interfaces.NoiseGeneratorSettingsProvider;
|
|||
import org.betterx.bclib.mixin.common.ChunkGeneratorAccessor;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.biomesource.MergeableBiomeSource;
|
||||
import org.betterx.worlds.together.biomesource.ReloadableBiomeSource;
|
||||
import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator;
|
||||
import org.betterx.worlds.together.chunkgenerator.InjectableSurfaceRules;
|
||||
import org.betterx.worlds.together.chunkgenerator.RestorableBiomeSource;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
@ -71,8 +73,8 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto
|
|||
) {
|
||||
super(registry, registry2, biomeSource, holder);
|
||||
initialBiomeSource = biomeSource;
|
||||
if (biomeSource instanceof BCLBiomeSource bcl) {
|
||||
bcl.setMaxHeight(holder.value().noiseSettings().height());
|
||||
if (biomeSource instanceof BiomeSourceWithNoiseRelatedSettings bcl) {
|
||||
bcl.onLoadGeneratorSettings(holder.value());
|
||||
}
|
||||
|
||||
if (WorldsTogether.RUNS_TERRABLENDER) {
|
||||
|
@ -109,6 +111,8 @@ public class BCLChunkGenerator extends NoiseBasedChunkGenerator implements Resto
|
|||
if (this instanceof ChunkGeneratorAccessor acc) {
|
||||
if (initialBiomeSource instanceof MergeableBiomeSource bs) {
|
||||
acc.bcl_setBiomeSource(bs.mergeWithBiomeSource(getBiomeSource()));
|
||||
} else if (initialBiomeSource instanceof ReloadableBiomeSource bs) {
|
||||
bs.reloadBiomes();
|
||||
}
|
||||
|
||||
rebuildFeaturesPerStep(getBiomeSource());
|
||||
|
|
|
@ -3,11 +3,12 @@ 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.BCLBiomeRegistry;
|
||||
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;
|
||||
import org.betterx.worlds.together.biomesource.ReloadableBiomeSource;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
@ -26,13 +27,14 @@ import net.minecraft.world.level.biome.Climate;
|
|||
import net.minecraft.world.level.levelgen.DensityFunction;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibEndBiomeSource, BCLEndBiomeSourceConfig> {
|
||||
public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibEndBiomeSource, BCLEndBiomeSourceConfig>, ReloadableBiomeSource {
|
||||
public static Codec<BCLibEndBiomeSource> CODEC
|
||||
= RecordCodecBuilder.create((instance) -> instance.group(
|
||||
RegistryOps
|
||||
|
@ -54,15 +56,18 @@ 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 BiomePicker endLandBiomePicker;
|
||||
private BiomePicker endVoidBiomePicker;
|
||||
private BiomePicker endCenterBiomePicker;
|
||||
private BiomePicker endBarrensBiomePicker;
|
||||
private List<BiomeDecider> deciders;
|
||||
|
||||
private BCLEndBiomeSourceConfig config;
|
||||
|
||||
|
@ -92,77 +97,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
) {
|
||||
super(biomeRegistry, list, seed);
|
||||
this.config = config;
|
||||
|
||||
endLandBiomePicker = new BiomePicker(biomeRegistry);
|
||||
endVoidBiomePicker = new BiomePicker(biomeRegistry);
|
||||
|
||||
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();
|
||||
|
||||
|
||||
if (!BiomeAPI.hasBiome(biomeID)) {
|
||||
BCLBiome bclBiome = new BCLBiome(biomeID, biome.value());
|
||||
|
||||
if (includeVoid.contains(biomeID.toString())) {
|
||||
endVoidBiomePicker.addBiome(bclBiome);
|
||||
} else {
|
||||
endLandBiomePicker.addBiome(bclBiome);
|
||||
}
|
||||
} else {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biomeID);
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() == null) {
|
||||
if (config.withVoidBiomes) {
|
||||
if (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID)
|
||||
|| 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 (BiomeAPI.wasRegisteredAsEndLandBiome(biomeID)
|
||||
|| TheEndBiomesHelper.isIntendedForEndLand(key)
|
||||
|| includeLand.contains(biomeID.toString())
|
||||
) {
|
||||
endLandBiomePicker.addBiome(bclBiome);
|
||||
endVoidBiomePicker.addBiome(bclBiome);
|
||||
}
|
||||
if (!biomeID.equals(Biomes.SMALL_END_ISLANDS.location()) && !biomeID.equals(Biomes.THE_END.location())
|
||||
&& (BiomeAPI.wasRegisteredAsEndVoidBiome(biomeID) || includeVoid.contains(biomeID.toString()))
|
||||
) {
|
||||
endVoidBiomePicker.addBiome(bclBiome);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
endLandBiomePicker.rebuild();
|
||||
endVoidBiomePicker.rebuild();
|
||||
|
||||
|
||||
this.centerBiome = biomeRegistry.getOrCreateHolderOrThrow(Biomes.THE_END);
|
||||
this.barrens = biomeRegistry.getOrCreateHolderOrThrow(Biomes.END_BARRENS);
|
||||
rebuildBiomePickers();
|
||||
|
||||
this.endLandFunction = GeneratorOptions.getEndLandFunction();
|
||||
this.pos = new Point();
|
||||
|
@ -172,11 +107,137 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private void rebuildBiomePickers() {
|
||||
var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap();
|
||||
var excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END);
|
||||
|
||||
this.deciders = BiomeDecider.DECIDERS.stream()
|
||||
.filter(d -> d.canProvideFor(this))
|
||||
.map(d -> d.createInstance(this))
|
||||
.toList();
|
||||
|
||||
this.endLandBiomePicker = new BiomePicker(biomeRegistry);
|
||||
this.endVoidBiomePicker = new BiomePicker(biomeRegistry);
|
||||
this.endCenterBiomePicker = new BiomePicker(biomeRegistry);
|
||||
this.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);
|
||||
|
||||
|
||||
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;
|
||||
if (!biome.isBound()) {
|
||||
BCLib.LOGGER.warning("Biome " + biomeStr + " is requested but not yet bound.");
|
||||
return;
|
||||
}
|
||||
final BCLBiome bclBiome;
|
||||
if (!BiomeAPI.hasBiome(biomeID)) {
|
||||
bclBiome = new BCLBiome(biomeID, biome.value());
|
||||
} else {
|
||||
bclBiome = BiomeAPI.getBiome(biomeID);
|
||||
}
|
||||
|
||||
|
||||
if (bclBiome != null || bclBiome != BCLBiomeRegistry.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 (biomeID.equals(BCLBiomeRegistry.EMPTY_BIOME.getID())
|
||||
|| bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_IGNORE)) {
|
||||
//we should not add this biome anywhere, so just ignore it
|
||||
} else {
|
||||
didForceAdd = false;
|
||||
for (BiomeDecider decider : deciders) {
|
||||
if (decider.addToPicker(bclBiome)) {
|
||||
didForceAdd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!didForceAdd) {
|
||||
if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_CENTER)
|
||||
|| TheEndBiomesHelper.canGenerateAsMainIslandBiome(key)) {
|
||||
endCenterBiomePicker.addBiome(bclBiome);
|
||||
} else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_LAND)
|
||||
|| TheEndBiomesHelper.canGenerateAsHighlandsBiome(key)) {
|
||||
if (!config.withVoidBiomes) endVoidBiomePicker.addBiome(bclBiome);
|
||||
endLandBiomePicker.addBiome(bclBiome);
|
||||
} else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_BARRENS)
|
||||
|| TheEndBiomesHelper.canGenerateAsEndBarrens(key)) {
|
||||
endBarrensBiomePicker.addBiome(bclBiome);
|
||||
} else if (bclBiome.getIntendedType().is(BiomeAPI.BiomeType.END_VOID)
|
||||
|| TheEndBiomesHelper.canGenerateAsSmallIslandsBiome(key)) {
|
||||
endVoidBiomePicker.addBiome(bclBiome);
|
||||
} else {
|
||||
BCLib.LOGGER.info("Found End Biome " + biomeStr + " that was not registers with fabric or bclib. Assuming end-land Biome...");
|
||||
endLandBiomePicker.addBiome(bclBiome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
endLandBiomePicker.rebuild();
|
||||
endVoidBiomePicker.rebuild();
|
||||
endBarrensBiomePicker.rebuild();
|
||||
endCenterBiomePicker.rebuild();
|
||||
|
||||
for (BiomeDecider decider : deciders) {
|
||||
decider.rebuild();
|
||||
}
|
||||
|
||||
if (endVoidBiomePicker.isEmpty()) {
|
||||
BCLib.LOGGER.info("No Void Biomes found. Disabling by using barrens");
|
||||
endVoidBiomePicker = endBarrensBiomePicker;
|
||||
}
|
||||
if (endBarrensBiomePicker.isEmpty()) {
|
||||
BCLib.LOGGER.info("No Barrens Biomes found. Disabling by using land Biomes");
|
||||
endBarrensBiomePicker = endLandBiomePicker;
|
||||
endVoidBiomePicker = endLandBiomePicker;
|
||||
}
|
||||
if (endCenterBiomePicker.isEmpty()) {
|
||||
BCLib.LOGGER.warning("No Center Island Biomes found. Forcing use of vanilla center.");
|
||||
endCenterBiomePicker.addBiome(BiomeAPI.THE_END);
|
||||
endCenterBiomePicker.rebuild();
|
||||
if (endCenterBiomePicker.isEmpty()) {
|
||||
BCLib.LOGGER.error("Unable to force vanilla central Island. Falling back to land Biomes...");
|
||||
endCenterBiomePicker = endLandBiomePicker;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected BCLBiomeSource cloneForDatapack(Set<Holder<Biome>> datapackBiomes) {
|
||||
datapackBiomes.addAll(getBclBiomes(this.biomeRegistry));
|
||||
return new BCLibEndBiomeSource(
|
||||
this.biomeRegistry,
|
||||
datapackBiomes.stream().toList(),
|
||||
datapackBiomes.stream()
|
||||
.filter(b -> b.unwrapKey().orElse(null) != BCLBiomeRegistry.EMPTY_BIOME.getBiomeKey())
|
||||
.toList(),
|
||||
this.currentSeed,
|
||||
this.config,
|
||||
true
|
||||
|
@ -184,51 +245,41 @@ 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.getExcludeMatching(BiomeAPI.BiomeType.END),
|
||||
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,
|
||||
Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END),
|
||||
Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.END),
|
||||
BCLibEndBiomeSource::isValidEndBiome
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private static boolean isValidEndBiome(Holder<Biome> biome, ResourceLocation location) {
|
||||
if (BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.END_IGNORE)) return false;
|
||||
|
||||
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) {
|
||||
if (BiomeAPI.wasRegisteredAs(location, BiomeAPI.BiomeType.END_IGNORE)) return false;
|
||||
|
||||
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() {
|
||||
|
@ -237,17 +288,36 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
|
||||
@Override
|
||||
protected void onInitMap(long seed) {
|
||||
this.mapLand = config.mapVersion.mapBuilder.apply(
|
||||
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,
|
||||
GeneratorOptions.getBiomeSizeEndLand(),
|
||||
config.landBiomesSize,
|
||||
endLandBiomePicker
|
||||
);
|
||||
|
||||
this.mapVoid = config.mapVersion.mapBuilder.apply(
|
||||
this.mapVoid = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
GeneratorOptions.getBiomeSizeEndVoid(),
|
||||
config.voidBiomesSize,
|
||||
endVoidBiomePicker
|
||||
);
|
||||
|
||||
this.mapCenter = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.centerBiomesSize,
|
||||
endCenterBiomePicker
|
||||
);
|
||||
|
||||
this.mapBarrens = config.mapVersion.mapBuilder.create(
|
||||
seed,
|
||||
config.barrensBiomesSize,
|
||||
endBarrensBiomePicker
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,7 +327,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);
|
||||
|
@ -268,39 +338,80 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
? ((long) config.innerVoidRadiusSquared + 1)
|
||||
: (long) posX * (long) posX + (long) posZ * (long) posZ;
|
||||
|
||||
if ((biomeX & 63) == 0 && (biomeZ & 63) == 0) {
|
||||
|
||||
if ((biomeX & 63) == 0 || (biomeZ & 63) == 0) {
|
||||
mapLand.clearCache();
|
||||
mapVoid.clearCache();
|
||||
mapCenter.clearCache();
|
||||
mapVoid.clearCache();
|
||||
for (BiomeDecider decider : deciders) {
|
||||
decider.clearMapCache();
|
||||
}
|
||||
}
|
||||
|
||||
if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA || endLandFunction == null) {
|
||||
if (dist <= (long) config.innerVoidRadiusSquared) {
|
||||
return this.centerBiome;
|
||||
}
|
||||
BiomeAPI.BiomeType suggestedType;
|
||||
|
||||
if (config.generatorVersion == BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA) {
|
||||
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;
|
||||
} else if (d >= -0.0625) {
|
||||
return mapLand.getBiome(posX, biomeY << 2, posZ).biome;
|
||||
if (dist <= (long) config.innerVoidRadiusSquared) {
|
||||
suggestedType = BiomeAPI.BiomeType.END_CENTER;
|
||||
} else {
|
||||
return d < -0.21875
|
||||
? mapVoid.getBiome(posX, biomeY << 2, posZ).biome
|
||||
: config.withVoidBiomes ? this.barrens : mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
|
||||
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
|
||||
);
|
||||
}
|
||||
} else {
|
||||
pos.setLocation(biomeX, biomeZ);
|
||||
if (endLandFunction.apply(pos, maxHeight)) {
|
||||
return dist <= (long) config.innerVoidRadiusSquared
|
||||
? centerBiome : mapLand.getBiome(posX, biomeY << 2, posZ).biome;
|
||||
} else {
|
||||
return dist <= (long) config.innerVoidRadiusSquared
|
||||
? barrens
|
||||
: mapVoid.getBiome(posX, biomeY << 2, posZ).biome;
|
||||
final BiomeAPI.BiomeType originalType = (dist <= (long) config.innerVoidRadiusSquared
|
||||
? BiomeAPI.BiomeType.END_CENTER
|
||||
: BiomeAPI.BiomeType.END_LAND);
|
||||
suggestedType = originalType;
|
||||
|
||||
for (BiomeDecider decider : deciders) {
|
||||
suggestedType = decider
|
||||
.suggestType(originalType, suggestedType, 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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -324,4 +435,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
this.config = newConfig;
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadBiomes() {
|
||||
rebuildBiomePickers();
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,15 @@ 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.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
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.bclib.util.TriFunction;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
|
||||
import org.betterx.worlds.together.biomesource.ReloadableBiomeSource;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
@ -27,7 +28,7 @@ import net.fabricmc.fabric.api.biome.v1.NetherBiomes;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibNetherBiomeSource, BCLNetherBiomeSourceConfig> {
|
||||
public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourceWithConfig<BCLibNetherBiomeSource, BCLNetherBiomeSourceConfig>, ReloadableBiomeSource {
|
||||
public static final Codec<BCLibNetherBiomeSource> CODEC = RecordCodecBuilder
|
||||
.create(instance -> instance
|
||||
.group(
|
||||
|
@ -50,7 +51,7 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
.apply(instance, instance.stable(BCLibNetherBiomeSource::new))
|
||||
);
|
||||
private BiomeMap biomeMap;
|
||||
private final BiomePicker biomePicker;
|
||||
private BiomePicker biomePicker;
|
||||
private BCLNetherBiomeSourceConfig config;
|
||||
|
||||
public BCLibNetherBiomeSource(Registry<Biome> biomeRegistry, BCLNetherBiomeSourceConfig config) {
|
||||
|
@ -79,18 +80,29 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
) {
|
||||
super(biomeRegistry, list, seed);
|
||||
this.config = config;
|
||||
rebuildBiomePicker();
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildBiomePicker() {
|
||||
biomePicker = new BiomePicker(biomeRegistry);
|
||||
|
||||
this.possibleBiomes().forEach(biome -> {
|
||||
ResourceLocation key = biome.unwrapKey().orElseThrow().location();
|
||||
ResourceLocation biomeID = biome.unwrapKey().orElseThrow().location();
|
||||
if (!biome.isBound()) {
|
||||
BCLib.LOGGER.warning("Biome " + biomeID.toString() + " is requested but not yet bound.");
|
||||
return;
|
||||
}
|
||||
if (!BiomeAPI.hasBiome(biomeID)) {
|
||||
|
||||
if (!BiomeAPI.hasBiome(key)) {
|
||||
BCLBiome bclBiome = new BCLBiome(key, biome.value());
|
||||
BCLBiome bclBiome = new BCLBiome(biomeID, biome.value());
|
||||
biomePicker.addBiome(bclBiome);
|
||||
} else {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(key);
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biomeID);
|
||||
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome != BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() == null) {
|
||||
biomePicker.addBiome(bclBiome);
|
||||
}
|
||||
|
@ -99,9 +111,6 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
});
|
||||
|
||||
biomePicker.rebuild();
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
protected BCLBiomeSource cloneForDatapack(Set<Holder<Biome>> datapackBiomes) {
|
||||
|
@ -116,20 +125,16 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
}
|
||||
|
||||
private static List<Holder<Biome>> getBclBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class)
|
||||
.getValue();
|
||||
List<String> exclude = Configs.BIOMES_CONFIG.getEntry("force_exclude", "nether_biomes", StringArrayEntry.class)
|
||||
.getValue();
|
||||
List<String> include = Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.NETHER);
|
||||
List<String> exclude = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.NETHER);
|
||||
|
||||
return getBiomes(biomeRegistry, exclude, include, BCLibNetherBiomeSource::isValidNonVanillaNetherBiome);
|
||||
}
|
||||
|
||||
|
||||
private static List<Holder<Biome>> getBiomes(Registry<Biome> biomeRegistry) {
|
||||
List<String> include = Configs.BIOMES_CONFIG.getEntry("force_include", "nether_biomes", StringArrayEntry.class)
|
||||
.getValue();
|
||||
List<String> exclude = Configs.BIOMES_CONFIG.getEntry("force_exclude", "nether_biomes", StringArrayEntry.class)
|
||||
.getValue();
|
||||
List<String> include = Configs.BIOMES_CONFIG.getIncludeMatching(BiomeAPI.BiomeType.NETHER);
|
||||
List<String> exclude = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.NETHER);
|
||||
|
||||
return getBiomes(biomeRegistry, exclude, include, BCLibNetherBiomeSource::isValidNetherBiome);
|
||||
}
|
||||
|
@ -176,20 +181,20 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
|
||||
@Override
|
||||
protected void onInitMap(long seed) {
|
||||
TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor = config.mapVersion.mapBuilder;
|
||||
if (maxHeight > 128 && GeneratorOptions.useVerticalBiomes()) {
|
||||
MapBuilderFunction mapConstructor = config.mapVersion.mapBuilder;
|
||||
if (maxHeight > config.biomeSizeVertical * 1.5 && config.useVerticalBiomes) {
|
||||
this.biomeMap = new MapStack(
|
||||
seed,
|
||||
GeneratorOptions.getBiomeSizeNether(),
|
||||
config.biomeSize,
|
||||
biomePicker,
|
||||
GeneratorOptions.getVerticalBiomeSizeNether(),
|
||||
config.biomeSizeVertical,
|
||||
maxHeight,
|
||||
mapConstructor
|
||||
);
|
||||
} else {
|
||||
this.biomeMap = mapConstructor.apply(
|
||||
this.biomeMap = mapConstructor.create(
|
||||
seed,
|
||||
GeneratorOptions.getBiomeSizeNether(),
|
||||
config.biomeSize,
|
||||
biomePicker
|
||||
);
|
||||
}
|
||||
|
@ -215,4 +220,10 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
this.config = newConfig;
|
||||
initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadBiomes() {
|
||||
rebuildBiomePicker();
|
||||
initMap(currentSeed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
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.Registry;
|
||||
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(
|
||||
Registry<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() {
|
||||
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,7 +1,7 @@
|
|||
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.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
import org.betterx.bclib.util.WeighTree;
|
||||
import org.betterx.bclib.util.WeightedList;
|
||||
|
||||
|
@ -23,6 +23,7 @@ public class BiomePicker {
|
|||
public final Registry<Biome> biomeRegistry;
|
||||
private final List<ActualBiome> biomes = Lists.newArrayList();
|
||||
private final List<String> allowedBiomes;
|
||||
public final ActualBiome fallbackBiome;
|
||||
private WeighTree<ActualBiome> tree;
|
||||
|
||||
public BiomePicker(Registry<Biome> biomeRegistry) {
|
||||
|
@ -36,6 +37,7 @@ public class BiomePicker {
|
|||
.map(h -> h.unwrapKey())
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get().location().toString()).toList() : null;
|
||||
this.fallbackBiome = create(BCLBiomeRegistry.EMPTY_BIOME);
|
||||
}
|
||||
|
||||
private boolean isAllowed(BCLBiome b) {
|
||||
|
@ -54,18 +56,34 @@ public class BiomePicker {
|
|||
}
|
||||
|
||||
public ActualBiome getBiome(WorldgenRandom random) {
|
||||
return biomes.isEmpty() ? null : tree.get(random);
|
||||
return biomes.isEmpty() ? fallbackBiome : tree.get(random);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return biomes.isEmpty();
|
||||
}
|
||||
|
||||
public void rebuild() {
|
||||
WeightedList<ActualBiome> list = new WeightedList<>();
|
||||
if (biomes.isEmpty()) {
|
||||
list.add(create(BiomeAPI.EMPTY_BIOME), 1);
|
||||
} else {
|
||||
biomes.forEach(biome -> {
|
||||
if (biome.isValid)
|
||||
list.add(biome, biome.bclBiome.getGenChance());
|
||||
});
|
||||
|
||||
biomes.forEach(biome -> {
|
||||
if (biome.isValid)
|
||||
list.add(biome, biome.bclBiome.getGenChance());
|
||||
});
|
||||
//only a single biome, we need to add the edges as well
|
||||
if (list.size() == 1) {
|
||||
ActualBiome biome = list.get(0);
|
||||
|
||||
if (biome.getEdge() != null) {
|
||||
float defaultBiomeSize = 128;
|
||||
float edgeSize = (biome.bclBiome.getEdgeSize() * list.getWeight(0)) / defaultBiomeSize;
|
||||
list.add(biome.getEdge(), edgeSize);
|
||||
}
|
||||
}
|
||||
|
||||
//no Biome, make sure we add at least one, otherwise bad things will happen
|
||||
if (list.isEmpty()) {
|
||||
list.add(create(BCLBiomeRegistry.EMPTY_BIOME), 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,7 +106,7 @@ public class BiomePicker {
|
|||
|
||||
this.key = biomeRegistry.getResourceKey(biomeRegistry.get(bclBiome.getID())).orElse(null);
|
||||
this.biome = key != null ? biomeRegistry.getOrCreateHolderOrThrow(key) : null;
|
||||
this.isValid = key != null;
|
||||
this.isValid = key != null && biome != null && biome.isBound();
|
||||
bclBiome.forEachSubBiome((b, w) -> {
|
||||
if (isAllowed(b))
|
||||
subbiomes.add(create(b), w);
|
||||
|
@ -131,5 +149,25 @@ public class BiomePicker {
|
|||
public boolean isSame(ActualBiome e) {
|
||||
return bclBiome.isSame(e.bclBiome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActualBiome{" +
|
||||
"key=" + key.location() +
|
||||
", subbiomes=" + subbiomes.size() +
|
||||
", edge=" + (edge != null ? edge.key.location() : "null") +
|
||||
", parent=" + (parent != null ? parent.key.location() : "null") +
|
||||
", isValid=" + isValid +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BiomePicker{" +
|
||||
"biomes=" + biomes.size() + " (" + all.size() + ")" +
|
||||
", biomeRegistry=" + biomeRegistry +
|
||||
", type=" + super.toString() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,55 +2,38 @@ package org.betterx.bclib.api.v2.generator;
|
|||
|
||||
import org.betterx.bclib.config.Configs;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.function.BiFunction;
|
||||
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;
|
||||
private static boolean verticalBiomes = true;
|
||||
private static long farEndBiomesSqr = 1000000;
|
||||
//private static BiFunction<Point, Integer, Boolean> endLandFunction;
|
||||
private static boolean fixEndBiomeSource = true;
|
||||
private static boolean fixNetherBiomeSource = true;
|
||||
|
||||
public static void init() {
|
||||
biomeSizeNether = Configs.GENERATOR_CONFIG.getInt("nether.biomeMap", "biomeSize", 256);
|
||||
biomeVSizeNether = Configs.GENERATOR_CONFIG.getInt(
|
||||
"nether.biomeMap",
|
||||
"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);
|
||||
fixEndBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixEndBiomeSource", true);
|
||||
fixNetherBiomeSource = Configs.GENERATOR_CONFIG.getBoolean("options.biomeSource", "fixNetherBiomeSource", true);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static int getBiomeSizeNether() {
|
||||
return Mth.clamp(biomeSizeNether, 1, 8192);
|
||||
return 256;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static int getVerticalBiomeSizeNether() {
|
||||
return Mth.clamp(biomeVSizeNether, 1, 8192);
|
||||
return 86;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,19 +42,22 @@ public class GeneratorOptions {
|
|||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void setEndLandFunction(Function<Point, Boolean> endLandFunction) {
|
||||
GeneratorOptions.endLandFunction = (p, h) -> endLandFunction.apply(p);
|
||||
//GeneratorOptions.endLandFunction = (p, h) -> endLandFunction.apply(p);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void setEndLandFunction(BiFunction<Point, Integer, Boolean> endLandFunction) {
|
||||
GeneratorOptions.endLandFunction = endLandFunction;
|
||||
///GeneratorOptions.endLandFunction = endLandFunction;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BiFunction<Point, Integer, Boolean> getEndLandFunction() {
|
||||
return endLandFunction;
|
||||
return (a, b) -> true;//endLandFunction;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static long getFarEndBiomes() {
|
||||
return farEndBiomesSqr;
|
||||
return 1000000;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -79,8 +65,8 @@ public class GeneratorOptions {
|
|||
*
|
||||
* @param distance
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void setFarEndBiomes(int distance) {
|
||||
GeneratorOptions.farEndBiomesSqr = (long) distance * (long) distance;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,21 +74,25 @@ public class GeneratorOptions {
|
|||
*
|
||||
* @param distanceSqr the distance squared
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static void setFarEndBiomesSqr(long distanceSqr) {
|
||||
GeneratorOptions.farEndBiomesSqr = distanceSqr;
|
||||
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean customNetherBiomeSource() {
|
||||
return customNetherBiomeSource;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean customEndBiomeSource() {
|
||||
return customEndBiomeSource;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean useVerticalBiomes() {
|
||||
return verticalBiomes;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean fixEndBiomeSource() {
|
||||
|
|
|
@ -1,96 +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
|
||||
private 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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package org.betterx.bclib.api.v2.generator;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
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(Registry<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,15 +1,14 @@
|
|||
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.BiomePicker;
|
||||
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
|
||||
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.bclib.util.TriFunction;
|
||||
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 +19,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
|
||||
VANILLA.innerVoidRadiusSquared * 16 * 16,
|
||||
256,
|
||||
256,
|
||||
256,
|
||||
256
|
||||
);
|
||||
public static final BCLEndBiomeSourceConfig MINECRAFT_18 = new BCLEndBiomeSourceConfig(
|
||||
EndBiomeMapType.HEX,
|
||||
EndBiomeGeneratorType.PAULEVS,
|
||||
false,
|
||||
MINECRAFT_17.innerVoidRadiusSquared
|
||||
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 DEFAULT = MINECRAFT_18;
|
||||
|
||||
|
@ -53,7 +64,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.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));
|
||||
|
||||
|
@ -61,12 +88,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 {
|
||||
|
@ -76,9 +111,9 @@ public class BCLEndBiomeSourceConfig implements BiomeSourceConfig<BCLibEndBiomeS
|
|||
|
||||
public static final Codec<EndBiomeMapType> CODEC = StringRepresentable.fromEnum(EndBiomeMapType::values);
|
||||
public final String name;
|
||||
public final @NotNull TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder;
|
||||
public final @NotNull MapBuilderFunction mapBuilder;
|
||||
|
||||
EndBiomeMapType(String name, @NotNull TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder) {
|
||||
EndBiomeMapType(String name, @NotNull MapBuilderFunction mapBuilder) {
|
||||
this.name = name;
|
||||
this.mapBuilder = mapBuilder;
|
||||
}
|
||||
|
@ -122,13 +157,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 +192,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
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package org.betterx.bclib.api.v2.generator.config;
|
||||
|
||||
import org.betterx.bclib.api.v2.generator.BCLibNetherBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.BiomePicker;
|
||||
import org.betterx.bclib.api.v2.generator.map.hex.HexBiomeMap;
|
||||
import org.betterx.bclib.api.v2.generator.map.square.SquareBiomeMap;
|
||||
import org.betterx.bclib.interfaces.BiomeMap;
|
||||
import org.betterx.bclib.util.TriFunction;
|
||||
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;
|
||||
|
@ -17,13 +15,22 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNetherBiomeSource> {
|
||||
public static final BCLNetherBiomeSourceConfig VANILLA = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.VANILLA
|
||||
NetherBiomeMapType.VANILLA,
|
||||
256,
|
||||
86,
|
||||
false
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_17 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.SQUARE
|
||||
NetherBiomeMapType.SQUARE,
|
||||
256,
|
||||
86,
|
||||
true
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig MINECRAFT_18 = new BCLNetherBiomeSourceConfig(
|
||||
NetherBiomeMapType.HEX
|
||||
NetherBiomeMapType.HEX,
|
||||
MINECRAFT_17.biomeSize,
|
||||
MINECRAFT_17.biomeSizeVertical,
|
||||
MINECRAFT_17.useVerticalBiomes
|
||||
);
|
||||
public static final BCLNetherBiomeSourceConfig DEFAULT = MINECRAFT_18;
|
||||
|
||||
|
@ -32,13 +39,32 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNether
|
|||
BCLNetherBiomeSourceConfig.NetherBiomeMapType.CODEC
|
||||
.fieldOf("map_type")
|
||||
.orElse(DEFAULT.mapVersion)
|
||||
.forGetter(o -> o.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)
|
||||
)
|
||||
.apply(instance, BCLNetherBiomeSourceConfig::new));
|
||||
public final @NotNull NetherBiomeMapType mapVersion;
|
||||
public final int biomeSize;
|
||||
public final int biomeSizeVertical;
|
||||
|
||||
public BCLNetherBiomeSourceConfig(@NotNull NetherBiomeMapType mapVersion) {
|
||||
public final boolean useVerticalBiomes;
|
||||
|
||||
public BCLNetherBiomeSourceConfig(
|
||||
@NotNull NetherBiomeMapType mapVersion,
|
||||
int biomeSize,
|
||||
int biomeSizeVertical,
|
||||
boolean useVerticalBiomes
|
||||
) {
|
||||
this.mapVersion = mapVersion;
|
||||
this.biomeSize = Mth.clamp(biomeSize, 1, 8192);
|
||||
this.biomeSizeVertical = Mth.clamp(biomeSizeVertical, 1, 8192);
|
||||
this.useVerticalBiomes = useVerticalBiomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,9 +107,9 @@ public class BCLNetherBiomeSourceConfig implements BiomeSourceConfig<BCLibNether
|
|||
|
||||
public static final Codec<NetherBiomeMapType> CODEC = StringRepresentable.fromEnum(NetherBiomeMapType::values);
|
||||
public final String name;
|
||||
public final TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder;
|
||||
public final MapBuilderFunction mapBuilder;
|
||||
|
||||
NetherBiomeMapType(String name, TriFunction<Long, Integer, BiomePicker, BiomeMap> mapBuilder) {
|
||||
NetherBiomeMapType(String name, MapBuilderFunction mapBuilder) {
|
||||
this.name = name;
|
||||
this.mapBuilder = mapBuilder;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
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,11 +1,11 @@
|
|||
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 org.betterx.bclib.util.TriFunction;
|
||||
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class MapStack implements BiomeMap {
|
|||
BiomePicker picker,
|
||||
int mapHeight,
|
||||
int worldHeight,
|
||||
TriFunction<Long, Integer, BiomePicker, BiomeMap> mapConstructor
|
||||
MapBuilderFunction mapConstructor
|
||||
) {
|
||||
final int mapCount = Mth.ceil((float) worldHeight / mapHeight);
|
||||
this.maxIndex = mapCount - 1;
|
||||
|
@ -37,7 +37,7 @@ public class MapStack implements BiomeMap {
|
|||
maps = new BiomeMap[mapCount];
|
||||
Random random = new Random(seed);
|
||||
for (int i = 0; i < mapCount; i++) {
|
||||
maps[i] = mapConstructor.apply(random.nextLong(), size, picker);
|
||||
maps[i] = mapConstructor.create(random.nextLong(), size, picker);
|
||||
maps[i].setChunkProcessor(this::onChunkCreation);
|
||||
}
|
||||
noise = new OpenSimplexNoise(random.nextInt());
|
||||
|
|
|
@ -7,7 +7,10 @@ import org.betterx.bclib.api.v2.datafixer.DataFixerAPI;
|
|||
import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource;
|
||||
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
|
||||
import org.betterx.bclib.api.v2.tag.TagAPI;
|
||||
import org.betterx.bclib.registry.PresetsRegistry;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
import org.betterx.worlds.together.world.WorldConfig;
|
||||
import org.betterx.worlds.together.world.event.WorldEvents;
|
||||
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPreset;
|
||||
|
@ -15,11 +18,14 @@ import org.betterx.worlds.together.worldPreset.WorldPreset;
|
|||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
@ -40,6 +46,21 @@ public class LevelGenEvents {
|
|||
|
||||
WorldEvents.PATCH_WORLD.on(LevelGenEvents::patchExistingWorld);
|
||||
WorldEvents.ADAPT_WORLD_PRESET.on(LevelGenEvents::adaptWorldPresetSettings);
|
||||
|
||||
WorldEvents.BEFORE_ADDING_TAGS.on(LevelGenEvents::appplyTags);
|
||||
}
|
||||
|
||||
private static void appplyTags(
|
||||
String directory,
|
||||
Map<ResourceLocation, List<TagLoader.EntryWithSource>> tagsMap
|
||||
) {
|
||||
//make sure we include Tags registered by the deprecated API
|
||||
TagAPI.apply(directory, tagsMap);
|
||||
|
||||
|
||||
if (directory.equals(TagManager.BIOMES.directory)) {
|
||||
InternalBiomeAPI._runBiomeTagAdders();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,7 +99,11 @@ public class LevelGenEvents {
|
|||
inputConfig.mapVersion,
|
||||
BCLEndBiomeSourceConfig.EndBiomeGeneratorType.VANILLA,
|
||||
false,
|
||||
inputConfig.innerVoidRadiusSquared
|
||||
inputConfig.innerVoidRadiusSquared,
|
||||
inputConfig.centerBiomesSize,
|
||||
inputConfig.voidBiomesSize,
|
||||
inputConfig.landBiomesSize,
|
||||
inputConfig.barrensBiomesSize
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +124,7 @@ public class LevelGenEvents {
|
|||
) {
|
||||
setupWorld();
|
||||
if (isNewWorld) {
|
||||
WorldConfig.saveFile(BCLib.MOD_ID);
|
||||
DataFixerAPI.initializePatchData();
|
||||
} else {
|
||||
LevelGenUtil.migrateGeneratorSettings();
|
||||
|
@ -113,6 +139,7 @@ public class LevelGenEvents {
|
|||
setupWorld();
|
||||
|
||||
if (isNewWorld) {
|
||||
WorldConfig.saveFile(BCLib.MOD_ID);
|
||||
DataFixerAPI.initializePatchData();
|
||||
} else {
|
||||
LevelGenUtil.migrateGeneratorSettings();
|
||||
|
|
|
@ -1,39 +1,190 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.biomes;
|
||||
|
||||
import org.betterx.bclib.util.WeightedList;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
|
||||
import com.mojang.datafixers.Products;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagKey;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.Climate;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BCLBiome extends BCLBiomeSettings {
|
||||
private final Set<TagKey<Biome>> biomeTags = Sets.newHashSet();
|
||||
private final WeightedList<BCLBiome> subbiomes = new WeightedList<>();
|
||||
|
||||
public class BCLBiome extends BCLBiomeSettings implements BiomeData {
|
||||
public static final Codec<BCLBiome> CODEC = RecordCodecBuilder.create(instance -> codecWithSettings(instance).apply(
|
||||
instance,
|
||||
BCLBiome::new
|
||||
));
|
||||
public static final KeyDispatchDataCodec<BCLBiome> KEY_CODEC = KeyDispatchDataCodec.of(CODEC);
|
||||
|
||||
public KeyDispatchDataCodec<? extends BCLBiome> codec() {
|
||||
return KEY_CODEC;
|
||||
}
|
||||
|
||||
private static class CodecAttributes<T extends BCLBiome> {
|
||||
public RecordCodecBuilder<T, Float> t0 = Codec.FLOAT.fieldOf("terrainHeight")
|
||||
.orElse(0.1f)
|
||||
.forGetter((T o1) -> o1.terrainHeight);
|
||||
|
||||
public RecordCodecBuilder<T, Float> t1 = Codec.FLOAT.fieldOf("fogDensity")
|
||||
.orElse(1.0f)
|
||||
.forGetter((T o1) -> o1.fogDensity);
|
||||
public RecordCodecBuilder<T, Float> t2 = Codec.FLOAT.fieldOf("genChance")
|
||||
.orElse(1.0f)
|
||||
.forGetter((T o1) -> o1.genChance);
|
||||
public RecordCodecBuilder<T, Integer> t3 = Codec.INT.fieldOf("edgeSize")
|
||||
.orElse(0)
|
||||
.forGetter((T o1) -> o1.edgeSize);
|
||||
public RecordCodecBuilder<T, Boolean> t4 = Codec.BOOL.fieldOf("vertical")
|
||||
.orElse(false)
|
||||
.forGetter((T o1) -> o1.vertical);
|
||||
public RecordCodecBuilder<T, Optional<ResourceLocation>> t5 =
|
||||
ResourceLocation.CODEC
|
||||
.optionalFieldOf("edge")
|
||||
.orElse(Optional.empty())
|
||||
.forGetter((T o1) -> o1.edge == null
|
||||
? Optional.empty()
|
||||
: Optional.of(o1.edge.biomeID));
|
||||
public RecordCodecBuilder<T, ResourceLocation> t6 =
|
||||
ResourceLocation.CODEC.fieldOf("biome")
|
||||
.forGetter((T o) -> ((BCLBiome) o).biomeID);
|
||||
public RecordCodecBuilder<T, Optional<List<Climate.ParameterPoint>>> t7 =
|
||||
Climate.ParameterPoint.CODEC.listOf()
|
||||
.optionalFieldOf("parameter_points")
|
||||
.orElse(Optional.of(List.of()))
|
||||
.forGetter((T o) ->
|
||||
o.parameterPoints == null || o.parameterPoints.isEmpty()
|
||||
? Optional.empty()
|
||||
: Optional.of(o.parameterPoints));
|
||||
|
||||
public RecordCodecBuilder<T, Optional<ResourceLocation>> t8 =
|
||||
ResourceLocation.CODEC.optionalFieldOf("parent")
|
||||
.orElse(Optional.empty())
|
||||
.forGetter(
|
||||
(T o1) ->
|
||||
((BCLBiome) o1).biomeParent == null
|
||||
? Optional.empty()
|
||||
: Optional.of(
|
||||
((BCLBiome) o1).biomeParent.biomeID));
|
||||
public RecordCodecBuilder<T, Optional<WeightedList<ResourceLocation>>> t9 =
|
||||
WeightedList.listCodec(
|
||||
ResourceLocation.CODEC,
|
||||
"biomes",
|
||||
"biome"
|
||||
)
|
||||
.optionalFieldOf("sub_biomes")
|
||||
.forGetter(
|
||||
(T o) -> {
|
||||
if (o.subbiomes == null
|
||||
|| o.subbiomes.isEmpty()
|
||||
|| (o.subbiomes.size() == 1 && o.subbiomes.contains(
|
||||
o))) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(
|
||||
o.subbiomes.map(
|
||||
b -> b.biomeID));
|
||||
});
|
||||
public RecordCodecBuilder<T, Optional<String>> t10 =
|
||||
Codec.STRING.optionalFieldOf("intended_for")
|
||||
.orElse(Optional.of(BiomeAPI.BiomeType.NONE.getName()))
|
||||
.forGetter((T o) ->
|
||||
((BCLBiome) o).intendedType == null
|
||||
? Optional.empty()
|
||||
: Optional.of(((BCLBiome) o).intendedType.getName()));
|
||||
}
|
||||
|
||||
public static <T extends BCLBiome, P12> Products.P12<RecordCodecBuilder.Mu<T>, Float, Float, Float, Integer, Boolean, Optional<ResourceLocation>, ResourceLocation, Optional<List<Climate.ParameterPoint>>, Optional<ResourceLocation>, Optional<WeightedList<ResourceLocation>>, Optional<String>, P12> codecWithSettings(
|
||||
RecordCodecBuilder.Instance<T> instance,
|
||||
final RecordCodecBuilder<T, P12> p12
|
||||
) {
|
||||
CodecAttributes<T> a = new CodecAttributes<>();
|
||||
return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12);
|
||||
}
|
||||
|
||||
public static <T extends BCLBiome, P12, P13> Products.P13<RecordCodecBuilder.Mu<T>, Float, Float, Float, Integer, Boolean, Optional<ResourceLocation>, ResourceLocation, Optional<List<Climate.ParameterPoint>>, Optional<ResourceLocation>, Optional<WeightedList<ResourceLocation>>, Optional<String>, P12, P13> codecWithSettings(
|
||||
RecordCodecBuilder.Instance<T> instance,
|
||||
final RecordCodecBuilder<T, P12> p12,
|
||||
final RecordCodecBuilder<T, P13> p13
|
||||
) {
|
||||
CodecAttributes<T> a = new CodecAttributes<>();
|
||||
return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12, p13);
|
||||
}
|
||||
|
||||
public static <T extends BCLBiome, P12, P13, P14> Products.P14<RecordCodecBuilder.Mu<T>, Float, Float, Float, Integer, Boolean, Optional<ResourceLocation>, ResourceLocation, Optional<List<Climate.ParameterPoint>>, Optional<ResourceLocation>, Optional<WeightedList<ResourceLocation>>, Optional<String>, P12, P13, P14> codecWithSettings(
|
||||
RecordCodecBuilder.Instance<T> instance,
|
||||
final RecordCodecBuilder<T, P12> p12,
|
||||
final RecordCodecBuilder<T, P13> p13,
|
||||
final RecordCodecBuilder<T, P14> p14
|
||||
) {
|
||||
CodecAttributes<T> a = new CodecAttributes<>();
|
||||
return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10, p12, p13, p14);
|
||||
}
|
||||
|
||||
public static <T extends BCLBiome> Products.P11<RecordCodecBuilder.Mu<T>, Float, Float, Float, Integer, Boolean, Optional<ResourceLocation>, ResourceLocation, Optional<List<Climate.ParameterPoint>>, Optional<ResourceLocation>, Optional<WeightedList<ResourceLocation>>, Optional<String>> codecWithSettings(
|
||||
RecordCodecBuilder.Instance<T> instance
|
||||
) {
|
||||
CodecAttributes<T> a = new CodecAttributes<>();
|
||||
return instance.group(a.t0, a.t1, a.t2, a.t3, a.t4, a.t5, a.t6, a.t7, a.t8, a.t9, a.t10);
|
||||
}
|
||||
|
||||
protected final WeightedList<BCLBiome> subbiomes = new WeightedList<>();
|
||||
private final Map<String, Object> customData = Maps.newHashMap();
|
||||
private final ResourceLocation biomeID;
|
||||
private final Biome biome;
|
||||
private final ResourceKey<Biome> biomeKey;
|
||||
final Biome biomeToRegister;
|
||||
|
||||
private final List<Climate.ParameterPoint> parameterPoints = Lists.newArrayList();
|
||||
protected final List<Climate.ParameterPoint> parameterPoints = Lists.newArrayList();
|
||||
|
||||
private BCLBiome biomeParent;
|
||||
|
||||
private BiomeAPI.BiomeType intendedType = BiomeAPI.BiomeType.NONE;
|
||||
|
||||
protected BCLBiome(
|
||||
float terrainHeight,
|
||||
float fogDensity,
|
||||
float genChance,
|
||||
int edgeSize,
|
||||
boolean vertical,
|
||||
Optional<ResourceLocation> edge,
|
||||
ResourceLocation biomeID,
|
||||
Optional<List<Climate.ParameterPoint>> parameterPoints,
|
||||
Optional<ResourceLocation> biomeParent,
|
||||
Optional<WeightedList<ResourceLocation>> subbiomes,
|
||||
Optional<String> intendedType
|
||||
) {
|
||||
super(terrainHeight, fogDensity, genChance, edgeSize, vertical, edge.map(BiomeAPI::getBiome).orElse(null));
|
||||
biomeToRegister = null;
|
||||
this.biomeID = biomeID;
|
||||
this.biomeKey = ResourceKey.create(Registry.BIOME_REGISTRY, biomeID);
|
||||
if (subbiomes.isEmpty() || subbiomes.get().size() == 0) {
|
||||
this.subbiomes.add(this, 1);
|
||||
} else {
|
||||
this.subbiomes.addAll(subbiomes.get().map(BiomeAPI::getBiome));
|
||||
}
|
||||
this.biomeParent = biomeParent.map(BiomeAPI::getBiome).orElse(null);
|
||||
if (parameterPoints.isPresent()) this.parameterPoints.addAll(parameterPoints.get());
|
||||
this.setIntendedType(intendedType.map(t -> BiomeAPI.BiomeType.create(t)).orElse(BiomeAPI.BiomeType.NONE));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper for existing biome using its {@link ResourceLocation} identifier.
|
||||
*
|
||||
|
@ -49,49 +200,100 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* @param biomeID {@link ResourceLocation} biome ID.
|
||||
*/
|
||||
protected BCLBiome(ResourceLocation biomeID) {
|
||||
this(biomeID, BuiltinRegistries.BIOME.get(biomeID), null);
|
||||
this(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}.
|
||||
*
|
||||
* @param biome {@link Biome} to wrap.
|
||||
* @param biomeToRegister {@link Biome} to wrap.
|
||||
*/
|
||||
protected BCLBiome(Biome biome) {
|
||||
this(biome, null);
|
||||
@Deprecated(forRemoval = true)
|
||||
protected BCLBiome(Biome biomeToRegister) {
|
||||
this(biomeToRegister, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}.
|
||||
*
|
||||
* @param biome {@link Biome} to wrap.
|
||||
* @param settings The Settings for this Biome or {@code null} if you want to apply default settings
|
||||
* @param biomeToRegister {@link Biome} to wrap.
|
||||
* @param settings The Settings for this Biome or {@code null} if you want to apply default settings
|
||||
*/
|
||||
protected BCLBiome(Biome biome, VanillaBiomeSettings settings) {
|
||||
this(BiomeAPI.getBiomeID(biome), biome, settings);
|
||||
@Deprecated(forRemoval = true)
|
||||
protected BCLBiome(Biome biomeToRegister, VanillaBiomeSettings settings) {
|
||||
this(BiomeAPI.getBiomeID(biomeToRegister), biomeToRegister, settings);
|
||||
}
|
||||
|
||||
public BCLBiome(ResourceLocation biomeID, Biome biome) {
|
||||
this(biomeID, biome, null);
|
||||
/**
|
||||
* Create wrapper for existing biome using biome instance from {@link BuiltinRegistries}.
|
||||
*
|
||||
* @param biomeToRegister {@link Biome} to wrap.
|
||||
* @param biomeID Teh ResoureLocation for this Biome
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
//this constructor should become package private and not get removed
|
||||
public BCLBiome(ResourceLocation biomeID, Biome biomeToRegister) {
|
||||
this(biomeID, biomeToRegister, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Biome
|
||||
*
|
||||
* @param biomeID {@link ResourceLocation} biome ID.
|
||||
* @param biome {@link Biome} to wrap.
|
||||
* @param biomeID {@link ResourceLocation} biome ID.
|
||||
* @param biomeToRegister {@link Biome} to wrap.
|
||||
* @param defaults The Settings for this Biome or null if you want to apply the defaults
|
||||
*/
|
||||
protected BCLBiome(ResourceLocation biomeID, Biome biomeToRegister, BCLBiomeSettings defaults) {
|
||||
this(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID), biomeToRegister, defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Biome
|
||||
*
|
||||
* @param biomeKey {@link ResourceKey<Biome>} of the wrapped Biome
|
||||
* @param defaults The Settings for this Biome or null if you want to apply the defaults
|
||||
*/
|
||||
protected BCLBiome(ResourceLocation biomeID, Biome biome, BCLBiomeSettings defaults) {
|
||||
protected BCLBiome(ResourceKey<Biome> biomeKey, BCLBiomeSettings defaults) {
|
||||
this(biomeKey, null, defaults);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Biome
|
||||
*
|
||||
* @param biomeKey {@link ResourceKey<Biome>} of the wrapped Biome
|
||||
* @param biomeToRegister The biome you want to use when this instance gets registered through the {@link BiomeAPI}
|
||||
* @param defaults The Settings for this Biome or null if you want to apply the defaults
|
||||
*/
|
||||
protected BCLBiome(ResourceKey<Biome> biomeKey, Biome biomeToRegister, BCLBiomeSettings defaults) {
|
||||
this.biomeToRegister = biomeToRegister;
|
||||
this.subbiomes.add(this, 1.0F);
|
||||
this.biomeID = biomeID;
|
||||
this.biome = biome;
|
||||
this.biomeID = biomeKey.location();
|
||||
this.biomeKey = biomeKey;
|
||||
|
||||
if (defaults != null) {
|
||||
defaults.applyWithDefaults(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the intended Type for this Biome
|
||||
*
|
||||
* @param type the new type
|
||||
* @return the same instance
|
||||
*/
|
||||
protected BCLBiome setIntendedType(BiomeAPI.BiomeType type) {
|
||||
return _setIntendedType(type);
|
||||
}
|
||||
|
||||
BCLBiome _setIntendedType(BiomeAPI.BiomeType type) {
|
||||
this.intendedType = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BiomeAPI.BiomeType getIntendedType() {
|
||||
return this.intendedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current biome edge.
|
||||
*
|
||||
|
@ -114,6 +316,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.
|
||||
|
@ -187,16 +405,30 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
*
|
||||
* @return {@link Biome}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public Biome getBiome() {
|
||||
return biome;
|
||||
if (biomeToRegister != null) return biomeToRegister;
|
||||
return BiomeAPI.getFromBuiltinRegistry(biomeKey).value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for biomeKey
|
||||
*
|
||||
* @return {@link ResourceKey<Biome>}.
|
||||
*/
|
||||
public ResourceKey<Biome> getBiomeKey() {
|
||||
return biomeKey;
|
||||
}
|
||||
|
||||
public ResourceKey<BCLBiome> getBCLBiomeKey() {
|
||||
return ResourceKey.create(BCLBiomeRegistry.BCL_BIOMES_REGISTRY, biomeID);
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use from BiomeAPI only
|
||||
*/
|
||||
void afterRegistration() {
|
||||
ResourceKey<Biome> key = BuiltinRegistries.BIOME.getResourceKey(getBiome()).orElseThrow();
|
||||
this.biomeTags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, biome));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -233,6 +465,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* @param obj any data to add.
|
||||
* @return same {@link BCLBiome}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLBiome addCustomData(String name, Object obj) {
|
||||
customData.put(name, obj);
|
||||
return this;
|
||||
|
@ -244,6 +477,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* @param data a {@link Map} with custom data.
|
||||
* @return same {@link BCLBiome}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public BCLBiome addCustomData(Map<String, Object> data) {
|
||||
customData.putAll(data);
|
||||
return this;
|
||||
|
@ -268,13 +502,6 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
return biomeID.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds structures to this biome. For internal use only.
|
||||
* Used inside {@link BCLBiomeBuilder}.
|
||||
*/
|
||||
void addBiomeTags(Set<TagKey<Biome>> tags) {
|
||||
biomeTags.addAll(tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds structures to this biome. For internal use only.
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.betterx.bclib.util.ColorUtil;
|
|||
import org.betterx.bclib.util.Pair;
|
||||
import org.betterx.bclib.util.TriFunction;
|
||||
import org.betterx.worlds.together.surfaceRules.SurfaceRuleRegistry;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
|
@ -53,6 +54,7 @@ public class BCLBiomeBuilder {
|
|||
public interface BiomeSupplier<T> extends TriFunction<ResourceLocation, Biome, BCLBiomeSettings, T> {
|
||||
}
|
||||
|
||||
|
||||
private static final BCLBiomeBuilder INSTANCE = new BCLBiomeBuilder();
|
||||
private static final SurfaceRules.ConditionSource SURFACE_NOISE = SurfaceRules.noiseCondition(
|
||||
Noises.SOUL_SAND_LAYER,
|
||||
|
@ -72,7 +74,6 @@ public class BCLBiomeBuilder {
|
|||
|
||||
private final List<Climate.ParameterPoint> parameters = Lists.newArrayList();
|
||||
|
||||
//BiomeTags.IS_NETHER
|
||||
private float temperature;
|
||||
private float fogDensity;
|
||||
private float genChance;
|
||||
|
@ -82,6 +83,8 @@ public class BCLBiomeBuilder {
|
|||
private BCLBiome edge;
|
||||
private boolean vertical;
|
||||
|
||||
private BiomeAPI.BiomeType biomeType;
|
||||
|
||||
|
||||
/**
|
||||
* Starts new biome building process.
|
||||
|
@ -106,6 +109,7 @@ public class BCLBiomeBuilder {
|
|||
INSTANCE.carvers.clear();
|
||||
INSTANCE.parameters.clear();
|
||||
INSTANCE.tags.clear();
|
||||
INSTANCE.biomeType = null;
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
|
@ -114,6 +118,17 @@ public class BCLBiomeBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type for this Biome. If the type was set, the Biome can be registered.
|
||||
*
|
||||
* @param type selected Type
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder type(BiomeAPI.BiomeType type) {
|
||||
this.biomeType = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set biome {@link Precipitation}. Affect biome visual effects (rain, snow, none).
|
||||
*
|
||||
|
@ -695,6 +710,64 @@ public class BCLBiomeBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the type for the Biome. The intended Type defines in which Dimension a
|
||||
* Biome is allowed to spawn. Currently each Biome can only spawn in one dimension
|
||||
*
|
||||
* @param type The intended type
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder intendedType(BiomeAPI.BiomeType type) {
|
||||
this.biomeType = type;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the intended type for the Biome to an EndLand Biome
|
||||
*
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder endLandBiome() {
|
||||
return intendedType(BiomeAPI.BiomeType.BCL_END_LAND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the intended type for the Biome to an EndVoid (aka small islands) Biome
|
||||
*
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder endVoidBiome() {
|
||||
return intendedType(BiomeAPI.BiomeType.BCL_END_VOID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the intended type for the Biome to an Endbarrens Biome
|
||||
*
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder endBarrensBiome() {
|
||||
return intendedType(BiomeAPI.BiomeType.BCL_END_BARRENS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the intended type for the Biome to an End Center Island Biome
|
||||
*
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder endCenterBiome() {
|
||||
return intendedType(BiomeAPI.BiomeType.BCL_END_CENTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the intended type for the Biome to a Nether Biome
|
||||
*
|
||||
* @return same {@link BCLBiomeBuilder} instance.
|
||||
*/
|
||||
public BCLBiomeBuilder netherBiome() {
|
||||
return intendedType(BiomeAPI.BiomeType.BCL_NETHER);
|
||||
}
|
||||
|
||||
public BCLBiomeBuilder tag(TagKey<Biome>... tag) {
|
||||
for (TagKey<Biome> t : tag) {
|
||||
tags.add(t);
|
||||
|
@ -724,26 +797,6 @@ public class BCLBiomeBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @return created {@link BCLBiome} instance.
|
||||
*/
|
||||
public BCLBiome build() {
|
||||
return build((BiomeSupplier<BCLBiome>) BCLBiome::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @param biomeConstructor {@link BiFunction} biome constructor.
|
||||
* @return created {@link BCLBiome} instance.
|
||||
* @deprecated Replaced with {@link #build(BiomeSupplier)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public <T extends BCLBiome> T build(BiFunction<ResourceLocation, Biome, T> biomeConstructor) {
|
||||
return build((id, biome, settings) -> biomeConstructor.apply(id, biome));
|
||||
}
|
||||
|
||||
private static BiomeGenerationSettings fixGenerationSettings(BiomeGenerationSettings settings) {
|
||||
//Fabric Biome Modification API can not handle an empty carver map, thus we will create one with
|
||||
|
@ -760,43 +813,6 @@ public class BCLBiomeBuilder {
|
|||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @param biomeConstructor {@link BiomeSupplier} biome constructor.
|
||||
* @return created {@link BCLBiome} instance.
|
||||
*/
|
||||
public <T extends BCLBiome> T build(BiomeSupplier<T> biomeConstructor) {
|
||||
BiomeBuilder builder = new BiomeBuilder()
|
||||
.precipitation(precipitation)
|
||||
.temperature(temperature)
|
||||
.downfall(downfall);
|
||||
|
||||
builder.mobSpawnSettings(getSpawns().build());
|
||||
builder.specialEffects(getEffects().build());
|
||||
|
||||
builder.generationSettings(fixGenerationSettings(getGeneration().build()));
|
||||
|
||||
BCLBiomeSettings settings = BCLBiomeSettings.createBCL()
|
||||
.setTerrainHeight(height)
|
||||
.setFogDensity(fogDensity)
|
||||
.setGenChance(genChance)
|
||||
.setEdgeSize(edgeSize)
|
||||
.setEdge(edge)
|
||||
.setVertical(vertical)
|
||||
.build();
|
||||
|
||||
final Biome biome = builder.build();
|
||||
final T res = biomeConstructor.apply(biomeID, biome, settings);
|
||||
res.addBiomeTags(tags);
|
||||
//res.setSurface(surfaceRule);
|
||||
SurfaceRuleRegistry.registerRule(biomeID, surfaceRule, biomeID);
|
||||
res.addClimateParameters(parameters);
|
||||
|
||||
|
||||
//carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first));
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create {@link BiomeSpecialEffects.Builder} for biome visual effects.
|
||||
|
@ -837,4 +853,67 @@ public class BCLBiomeBuilder {
|
|||
}
|
||||
return generationSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @return created {@link BCLBiome} instance.
|
||||
*/
|
||||
public BCLBiome build() {
|
||||
return build((BiomeSupplier<BCLBiome>) BCLBiome::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @param biomeConstructor {@link BiFunction} biome constructor.
|
||||
* @return created {@link BCLBiome} instance.
|
||||
* @deprecated Replaced with {@link #build(BiomeSupplier)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public <T extends BCLBiome> T build(BiFunction<ResourceLocation, Biome, T> biomeConstructor) {
|
||||
return build((id, biome, settings) -> biomeConstructor.apply(id, biome));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize biome creation.
|
||||
*
|
||||
* @param biomeConstructor {@link BiomeSupplier} biome constructor.
|
||||
* @return created {@link BCLBiome} instance.
|
||||
*/
|
||||
public <T extends BCLBiome> T build(BiomeSupplier<T> biomeConstructor) {
|
||||
BiomeBuilder builder = new BiomeBuilder()
|
||||
.precipitation(precipitation)
|
||||
.temperature(temperature)
|
||||
.downfall(downfall);
|
||||
|
||||
builder.mobSpawnSettings(getSpawns().build());
|
||||
builder.specialEffects(getEffects().build());
|
||||
|
||||
builder.generationSettings(fixGenerationSettings(getGeneration().build()));
|
||||
|
||||
BCLBiomeSettings settings = BCLBiomeSettings.createBCL()
|
||||
.setTerrainHeight(height)
|
||||
.setFogDensity(fogDensity)
|
||||
.setGenChance(genChance)
|
||||
.setEdgeSize(edgeSize)
|
||||
.setEdge(edge)
|
||||
.setVertical(vertical)
|
||||
.build();
|
||||
|
||||
final Biome biome = builder.build();
|
||||
final T res = biomeConstructor.apply(biomeID, biome, settings);
|
||||
tags.forEach(tagKey -> TagManager.BIOMES.add(tagKey, res.getBiomeKey()));
|
||||
|
||||
//res.addBiomeTags(tags);
|
||||
//res.setSurface(surfaceRule);
|
||||
SurfaceRuleRegistry.registerRule(biomeID, surfaceRule, biomeID);
|
||||
res.addClimateParameters(parameters);
|
||||
if (biomeType != null)
|
||||
res._setIntendedType(biomeType);
|
||||
|
||||
|
||||
//carvers.forEach(cfg -> BiomeAPI.addBiomeCarver(biome, cfg.second, cfg.first));
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.biomes;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
public class BCLBiomeRegistry {
|
||||
public static final ResourceKey<Registry<BCLBiome>> BCL_BIOMES_REGISTRY =
|
||||
createRegistryKey(WorldsTogether.makeID("worldgen/betterx/biome"));
|
||||
|
||||
public static final ResourceKey<Registry<Codec<? extends BCLBiome>>> BCL_BIOME_CODEC_REGISTRY =
|
||||
createRegistryKey(WorldsTogether.makeID("worldgen/betterx/biome_codec"));
|
||||
|
||||
public static Registry<Codec<? extends BCLBiome>> BIOME_CODECS = Registry.registerSimple(
|
||||
BCL_BIOME_CODEC_REGISTRY,
|
||||
BCLBiomeRegistry::bootstrapCodecs
|
||||
);
|
||||
public static Registry<BCLBiome> BUILTIN_BCL_BIOMES = new MappedRegistry<>(
|
||||
BCL_BIOMES_REGISTRY,
|
||||
Lifecycle.stable(), null
|
||||
);
|
||||
|
||||
/**
|
||||
* Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs.
|
||||
* Have {@code Biomes.THE_VOID} as the reference biome.
|
||||
**/
|
||||
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location());
|
||||
|
||||
public static Codec<? extends BCLBiome> registerBiomeCodec(
|
||||
ResourceLocation location,
|
||||
KeyDispatchDataCodec<? extends BCLBiome> codec
|
||||
) {
|
||||
Registry.register(BIOME_CODECS, location, codec.codec());
|
||||
return codec.codec();
|
||||
}
|
||||
|
||||
public static ResourceKey<BCLBiome> register(BCLBiome biome) {
|
||||
Registry.register(BUILTIN_BCL_BIOMES, biome.getBCLBiomeKey(), biome);
|
||||
return biome.getBCLBiomeKey();
|
||||
}
|
||||
|
||||
private static <T> ResourceKey<Registry<T>> createRegistryKey(ResourceLocation location) {
|
||||
return ResourceKey.createRegistryKey(location);
|
||||
}
|
||||
|
||||
private static Codec<? extends BCLBiome> bootstrapCodecs(Registry<Codec<? extends BCLBiome>> registry) {
|
||||
return Registry.register(registry, BCLib.makeID("biome"), BCLBiome.KEY_CODEC.codec());
|
||||
}
|
||||
|
||||
|
||||
@ApiStatus.Internal
|
||||
public static Holder<BCLBiome> bootstrap(Registry<BCLBiome> registry) {
|
||||
BuiltinRegistries.register(registry, BiomeAPI.SMALL_END_ISLANDS.getBCLBiomeKey(), BiomeAPI.SMALL_END_ISLANDS);
|
||||
BuiltinRegistries.register(registry, BiomeAPI.END_BARRENS.getBCLBiomeKey(), BiomeAPI.END_BARRENS);
|
||||
BuiltinRegistries.register(registry, BiomeAPI.END_HIGHLANDS.getBCLBiomeKey(), BiomeAPI.END_HIGHLANDS);
|
||||
BuiltinRegistries.register(registry, BiomeAPI.END_MIDLANDS.getBCLBiomeKey(), BiomeAPI.END_MIDLANDS);
|
||||
BuiltinRegistries.register(registry, BiomeAPI.THE_END.getBCLBiomeKey(), BiomeAPI.THE_END);
|
||||
BuiltinRegistries.register(
|
||||
registry,
|
||||
BiomeAPI.BASALT_DELTAS_BIOME.getBCLBiomeKey(),
|
||||
BiomeAPI.BASALT_DELTAS_BIOME
|
||||
);
|
||||
BuiltinRegistries.register(
|
||||
registry,
|
||||
BiomeAPI.SOUL_SAND_VALLEY_BIOME.getBCLBiomeKey(),
|
||||
BiomeAPI.SOUL_SAND_VALLEY_BIOME
|
||||
);
|
||||
BuiltinRegistries.register(
|
||||
registry,
|
||||
BiomeAPI.WARPED_FOREST_BIOME.getBCLBiomeKey(),
|
||||
BiomeAPI.WARPED_FOREST_BIOME
|
||||
);
|
||||
BuiltinRegistries.register(
|
||||
registry,
|
||||
BiomeAPI.CRIMSON_FOREST_BIOME.getBCLBiomeKey(),
|
||||
BiomeAPI.CRIMSON_FOREST_BIOME
|
||||
);
|
||||
BuiltinRegistries.register(
|
||||
registry,
|
||||
BiomeAPI.NETHER_WASTES_BIOME.getBCLBiomeKey(),
|
||||
BiomeAPI.NETHER_WASTES_BIOME
|
||||
);
|
||||
return BuiltinRegistries.register(registry, EMPTY_BIOME.getBCLBiomeKey(), EMPTY_BIOME);
|
||||
}
|
||||
|
||||
public static BCLBiome get(ResourceLocation loc) {
|
||||
return get(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), loc);
|
||||
}
|
||||
|
||||
public static BCLBiome get(RegistryAccess access, ResourceLocation loc) {
|
||||
return getBclBiomesRegistry(access).get(loc);
|
||||
}
|
||||
|
||||
public static BCLBiome getOrElseEmpty(ResourceLocation loc) {
|
||||
return getOrElseEmpty(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), loc);
|
||||
}
|
||||
|
||||
public static BCLBiome getOrElseEmpty(RegistryAccess access, ResourceLocation loc) {
|
||||
BCLBiome res = get(access, loc);
|
||||
if (res == null) return EMPTY_BIOME;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static Stream<ResourceKey<BCLBiome>> getAll(BiomeAPI.BiomeType dim) {
|
||||
return getAll(WorldBootstrap.getLastRegistryAccessOrElseBuiltin(), dim);
|
||||
}
|
||||
|
||||
public static Stream<ResourceKey<BCLBiome>> getAll(RegistryAccess access, BiomeAPI.BiomeType dim) {
|
||||
return getBclBiomesRegistry(access)
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().getIntendedType().is(BiomeAPI.BiomeType.END))
|
||||
.map(e -> e.getKey());
|
||||
}
|
||||
|
||||
private static Registry<BCLBiome> getBclBiomesRegistry(RegistryAccess access) {
|
||||
if (access != null) {
|
||||
return ((Optional<Registry<BCLBiome>>) access
|
||||
.registry(BCLBiomeRegistry.BCL_BIOMES_REGISTRY))
|
||||
.orElse(BUILTIN_BCL_BIOMES);
|
||||
} else {
|
||||
return BUILTIN_BCL_BIOMES;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ensureStaticallyLoaded() {
|
||||
|
||||
}
|
||||
}
|
|
@ -103,6 +103,22 @@ public class BCLBiomeSettings {
|
|||
}
|
||||
}
|
||||
|
||||
BCLBiomeSettings(
|
||||
float terrainHeight,
|
||||
float fogDensity,
|
||||
float genChance,
|
||||
int edgeSize,
|
||||
boolean vertical,
|
||||
BCLBiome edge
|
||||
) {
|
||||
this.terrainHeight = terrainHeight;
|
||||
this.fogDensity = fogDensity;
|
||||
this.genChance = genChance;
|
||||
this.edgeSize = edgeSize;
|
||||
this.vertical = vertical;
|
||||
this.edge = edge;
|
||||
}
|
||||
|
||||
protected BCLBiomeSettings() {
|
||||
this.terrainHeight = 0.1F;
|
||||
this.fogDensity = 1.0F;
|
||||
|
|
|
@ -8,8 +8,10 @@ import org.betterx.bclib.mixin.common.MobSpawnSettingsAccessor;
|
|||
import org.betterx.bclib.util.CollectionsUtil;
|
||||
import org.betterx.worlds.together.tag.v3.CommonBiomeTags;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet;
|
||||
|
@ -26,7 +28,6 @@ import net.minecraft.world.level.Level;
|
|||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeGenerationSettings;
|
||||
import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.biome.MobSpawnSettings.SpawnerData;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -38,52 +39,142 @@ import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.biome.v1.NetherBiomes;
|
||||
import net.fabricmc.fabric.api.biome.v1.TheEndBiomes;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BiomeAPI {
|
||||
public static class BiomeType {
|
||||
public static final Codec<BiomeType> DIRECT_CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
Codec.STRING.fieldOf("name")
|
||||
.orElse("undefined")
|
||||
.forGetter(o -> o.name)
|
||||
|
||||
).apply(instance, BiomeType::create));
|
||||
public static final Codec<BiomeType> CODEC = RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
Codec.STRING.fieldOf("name")
|
||||
.orElse("undefined")
|
||||
.forGetter(o -> o.name),
|
||||
Codec.STRING.fieldOf("parent")
|
||||
.orElse("none")
|
||||
.forGetter(o -> o.parentOrNull == null ? "none" : o.parentOrNull.name)
|
||||
|
||||
).apply(instance, BiomeType::create));
|
||||
|
||||
private static final Map<String, BiomeType> KNOWN_TYPES = new HashMap<>();
|
||||
|
||||
public static final BiomeType NONE = new BiomeType("NONE");
|
||||
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 BCL_NETHER = new BiomeType("BCL_NETHER", NETHER, (biome, ignored) -> {
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
biome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
|
||||
}
|
||||
});
|
||||
public static final BiomeType END = new BiomeType("END");
|
||||
public static final BiomeType END_IGNORE = new BiomeType("END_IGNORE", 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 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 END_BARRENS = new BiomeType("END_BARRENS", END);
|
||||
public static final BiomeType BCL_END_LAND = new BiomeType("BCL_END_LAND", END_LAND, (biome, ignored) -> {
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
|
||||
if (biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = biome.getParentBiome().getBiomeKey();
|
||||
TheEndBiomes.addMidlandsBiome(parentKey, key, weight);
|
||||
} else {
|
||||
TheEndBiomes.addHighlandsBiome(key, weight);
|
||||
}
|
||||
});
|
||||
public static final BiomeType BCL_END_VOID = new BiomeType("BCL_END_VOID", END_VOID, (biome, ignored) -> {
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
TheEndBiomes.addSmallIslandsBiome(key, weight);
|
||||
}
|
||||
});
|
||||
public static final BiomeType BCL_END_CENTER = new BiomeType("BCL_END_CENTER", END_CENTER, (biome, ignored) -> {
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
TheEndBiomes.addMainIslandBiome(key, weight);
|
||||
}
|
||||
});
|
||||
|
||||
public static final BiomeType BCL_END_BARRENS = new BiomeType(
|
||||
"BCL_END_BARRENS",
|
||||
END_BARRENS,
|
||||
(biome, highlandBiome) -> {
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = highlandBiome.getBiomeKey();
|
||||
TheEndBiomes.addBarrensBiome(parentKey, key, weight);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
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);
|
||||
@FunctionalInterface
|
||||
interface ExtraRegisterTaks {
|
||||
void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent);
|
||||
}
|
||||
|
||||
public BiomeType(String debugName, BiomeType parentOrNull) {
|
||||
final ExtraRegisterTaks extraRegisterTask;
|
||||
|
||||
private static BiomeType create(String name, String parentOrNull) {
|
||||
BiomeType known = KNOWN_TYPES.get(name);
|
||||
BiomeType parent = parentOrNull == null || "none".equals(parentOrNull)
|
||||
? null
|
||||
: KNOWN_TYPES.get(parentOrNull);
|
||||
if (known != null) {
|
||||
if (known.parentOrNull != parent) {
|
||||
BCLib.LOGGER.warning("BiomeType " + name + " was deserialized with parent " + parent + " but already has " + known.parentOrNull);
|
||||
}
|
||||
return known;
|
||||
}
|
||||
return new BiomeType(name, parent);
|
||||
}
|
||||
|
||||
static BiomeType create(String name) {
|
||||
BiomeType known = KNOWN_TYPES.get(name);
|
||||
if (known != null) {
|
||||
return known;
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
|
||||
public BiomeType(String name) {
|
||||
this(name, null);
|
||||
}
|
||||
|
||||
public BiomeType(String name, BiomeType parentOrNull) {
|
||||
this(name, parentOrNull, (b, a) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public BiomeType(String name, BiomeType parentOrNull, ExtraRegisterTaks extraRegisterTask) {
|
||||
this.parentOrNull = parentOrNull;
|
||||
this.debugName = debugName;
|
||||
this.name = name;
|
||||
this.extraRegisterTask = extraRegisterTask;
|
||||
KNOWN_TYPES.put(name, this);
|
||||
}
|
||||
|
||||
public boolean is(BiomeType d) {
|
||||
|
@ -92,44 +183,101 @@ 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
BiomeType biomeType = (BiomeType) o;
|
||||
return name.equals(biomeType.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty biome used as default value if requested biome doesn't exist or linked. Shouldn't be registered anywhere to prevent bugs.
|
||||
* Have {@code Biomes.THE_VOID} as the reference biome.
|
||||
*
|
||||
* @deprecated use {@link BCLBiomeRegistry#EMPTY_BIOME} instead
|
||||
*/
|
||||
public static final BCLBiome EMPTY_BIOME = new BCLBiome(Biomes.THE_VOID.location());
|
||||
public static final BCLBiome EMPTY_BIOME = BCLBiomeRegistry.EMPTY_BIOME;
|
||||
|
||||
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_MIDLANDS = registerSubBiome(
|
||||
THE_END,
|
||||
getFromRegistry(Biomes.END_MIDLANDS).value(),
|
||||
0.5F
|
||||
public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome(
|
||||
Biomes.NETHER_WASTES,
|
||||
InternalBiomeAPI.OTHER_NETHER
|
||||
);
|
||||
public static final BCLBiome END_HIGHLANDS = registerSubBiome(
|
||||
THE_END,
|
||||
getFromRegistry(Biomes.END_HIGHLANDS).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.
|
||||
*
|
||||
* @param bclbiome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerBiome(BCLBiome bclbiome) {
|
||||
return registerBiome(bclbiome, BuiltinRegistries.BIOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
|
@ -138,20 +286,46 @@ public class BiomeAPI {
|
|||
* @param dim The Dimension fo rthis Biome
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim) {
|
||||
if (BuiltinRegistries.BIOME.get(bclbiome.getID()) == null) {
|
||||
final Biome biome = bclbiome.getBiome();
|
||||
ResourceLocation loc = bclbiome.getID();
|
||||
Registry.register(BuiltinRegistries.BIOME, loc, biome);
|
||||
return registerBiome(bclbiome, dim, BuiltinRegistries.BIOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
*
|
||||
* @param bclbiome {@link BCLBiome}
|
||||
* @param dim The Dimension fo rthis Biome
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim, Registry<Biome> registryOrNull) {
|
||||
bclbiome._setIntendedType(dim);
|
||||
return registerBiome(bclbiome, registryOrNull);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
*
|
||||
* @param bclbiome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
static BCLBiome registerBiome(BCLBiome bclbiome, Registry<Biome> registryOrNull) {
|
||||
BiomeType dim = bclbiome.getIntendedType();
|
||||
if (registryOrNull != null
|
||||
&& bclbiome.biomeToRegister != null
|
||||
&& registryOrNull.get(bclbiome.getID()) == null) {
|
||||
Registry.register(registryOrNull, bclbiome.getBiomeKey(), bclbiome.biomeToRegister);
|
||||
|
||||
BCLBiomeRegistry.register(bclbiome);
|
||||
}
|
||||
ID_MAP.put(bclbiome.getID(), bclbiome);
|
||||
BiomeType.BIOME_TYPE_MAP.put(bclbiome.getID(), dim);
|
||||
|
||||
if (dim != null && dim.is(BiomeType.NETHER)) {
|
||||
TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiome());
|
||||
TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome.getBiome());
|
||||
TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiomeKey());
|
||||
TagManager.BIOMES.add(CommonBiomeTags.IN_NETHER, bclbiome.getBiomeKey());
|
||||
} else if (dim != null && dim.is(BiomeType.END)) {
|
||||
TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome.getBiome());
|
||||
TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome.getBiomeKey());
|
||||
TagManager.BIOMES.add(CommonBiomeTags.IN_END, bclbiome.getBiomeKey());
|
||||
}
|
||||
|
||||
bclbiome.afterRegistration();
|
||||
|
@ -163,7 +337,7 @@ public class BiomeAPI {
|
|||
return registerSubBiome(
|
||||
parent,
|
||||
subBiome,
|
||||
BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE)
|
||||
parent.getIntendedType()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -172,7 +346,7 @@ public class BiomeAPI {
|
|||
parent,
|
||||
subBiome,
|
||||
genChance,
|
||||
BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE)
|
||||
parent.getIntendedType()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -188,36 +362,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).
|
||||
|
@ -229,49 +373,18 @@ public class BiomeAPI {
|
|||
registerBiome(biome, BiomeType.BCL_END_LAND);
|
||||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = getBiomeKey(biome.getBiome());
|
||||
if (biome.allowFabricRegistration()) {
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
|
||||
if (biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = biome.getParentBiome().getBiomeKey();
|
||||
TheEndBiomes.addMidlandsBiome(parentKey, key, weight);
|
||||
} else {
|
||||
TheEndBiomes.addHighlandsBiome(key, weight);
|
||||
TheEndBiomes.addMidlandsBiome(key, key, weight);
|
||||
if (biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = getBiomeKey(biome.getParentBiome().getBiome());
|
||||
TheEndBiomes.addMidlandsBiome(parentKey, 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.
|
||||
|
@ -284,8 +397,8 @@ public class BiomeAPI {
|
|||
registerBiome(biome, BiomeType.BCL_END_VOID);
|
||||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = getBiomeKey(biome.getBiome());
|
||||
if (biome.allowFabricRegistration()) {
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
TheEndBiomes.addSmallIslandsBiome(key, weight);
|
||||
}
|
||||
return biome;
|
||||
|
@ -293,61 +406,78 @@ 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.END_VOID);
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
public static BCLBiome registerEndBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
registerBiome(bclBiome, BiomeType.END);
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
public static BCLBiome registerCenterBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
registerBiome(bclBiome, BiomeType.END_CENTER);
|
||||
return bclBiome;
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
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 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 barrens island
|
||||
* biome (will generate on the edge of midland biomes on the larger islands).
|
||||
*
|
||||
* @param biome {@link BCLBiome}.
|
||||
* @param genChance float generation chance.
|
||||
* @param biome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerEndVoidBiome(Holder<Biome> biome, float genChance) {
|
||||
BCLBiome bclBiome = new BCLBiome(
|
||||
biome.value(),
|
||||
VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
|
||||
);
|
||||
public static BCLBiome registerEndBarrensBiome(BCLBiome highlandBiome, BCLBiome biome) {
|
||||
registerBiome(biome, BiomeType.BCL_END_BARRENS);
|
||||
|
||||
registerBiome(bclBiome, BiomeType.END_VOID);
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (!biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = highlandBiome.getBiomeKey();
|
||||
TheEndBiomes.addBarrensBiome(parentKey, key, weight);
|
||||
}
|
||||
return biome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 = bclBiome.getBiomeKey();
|
||||
if (!bclBiome.isEdgeBiome()) {
|
||||
bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
|
||||
}
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get {@link BCLBiome} from {@link Biome} instance on server. Used to convert world biomes to BCLBiomes.
|
||||
*
|
||||
* @param biome - {@link Holder<Biome>} from world.
|
||||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLBiome getFromBiome(Holder<Biome> biome) {
|
||||
if (InternalBiomeAPI.biomeRegistry == null) {
|
||||
return EMPTY_BIOME;
|
||||
return BCLBiomeRegistry.EMPTY_BIOME;
|
||||
}
|
||||
return ID_MAP.getOrDefault(biome.unwrapKey().orElseThrow().location(), EMPTY_BIOME);
|
||||
return BCLBiomeRegistry
|
||||
.getOrElseEmpty(
|
||||
InternalBiomeAPI.registryAccess,
|
||||
biome.unwrapKey().orElseThrow().location()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -356,15 +486,15 @@ public class BiomeAPI {
|
|||
* @param biome - {@link Biome} from client world.
|
||||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public static BCLBiome getRenderBiome(Biome biome) {
|
||||
BCLBiome endBiome = InternalBiomeAPI.CLIENT.get(biome);
|
||||
if (endBiome == null) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
ResourceLocation id = minecraft.level.registryAccess()
|
||||
.registryOrThrow(Registry.BIOME_REGISTRY)
|
||||
.getKey(biome);
|
||||
endBiome = id == null ? EMPTY_BIOME : ID_MAP.getOrDefault(id, EMPTY_BIOME);
|
||||
ResourceLocation id = WorldBootstrap.getLastRegistryAccessOrElseBuiltin()
|
||||
.registryOrThrow(Registry.BIOME_REGISTRY)
|
||||
.getKey(biome);
|
||||
endBiome = id == null
|
||||
? BCLBiomeRegistry.EMPTY_BIOME
|
||||
: BCLBiomeRegistry.getOrElseEmpty(id);
|
||||
InternalBiomeAPI.CLIENT.put(biome, endBiome);
|
||||
}
|
||||
return endBiome;
|
||||
|
@ -404,7 +534,7 @@ public class BiomeAPI {
|
|||
|
||||
if (id == null) {
|
||||
BCLib.LOGGER.error("Unable to get ID for " + biome + ". Falling back to empty Biome...");
|
||||
id = EMPTY_BIOME.getID();
|
||||
id = BCLBiomeRegistry.EMPTY_BIOME.getID();
|
||||
}
|
||||
|
||||
return id;
|
||||
|
@ -417,11 +547,10 @@ public class BiomeAPI {
|
|||
* @return biome {@link ResourceLocation}.
|
||||
*/
|
||||
public static ResourceLocation getBiomeID(Holder<Biome> biome) {
|
||||
var oKey = biome.unwrapKey();
|
||||
if (oKey.isPresent()) {
|
||||
return oKey.get().location();
|
||||
}
|
||||
return null;
|
||||
return biome
|
||||
.unwrapKey()
|
||||
.map(h -> h.location())
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
public static ResourceKey getBiomeKey(Holder<Biome> biome) {
|
||||
|
@ -433,23 +562,29 @@ public class BiomeAPI {
|
|||
}
|
||||
|
||||
public static Holder<Biome> getBiomeHolder(BCLBiome biome) {
|
||||
return getBiomeHolder(biome.getBiome());
|
||||
return getBiomeHolder(biome.getBiomeKey());
|
||||
}
|
||||
|
||||
public static Holder<Biome> getBiomeHolder(Biome biome) {
|
||||
Optional<ResourceKey<Biome>> key = Optional.empty();
|
||||
if (InternalBiomeAPI.biomeRegistry != null) {
|
||||
Optional<ResourceKey<Biome>> key = InternalBiomeAPI.biomeRegistry.getResourceKey(biome);
|
||||
if (key.isPresent()) return InternalBiomeAPI.biomeRegistry.getOrCreateHolder(key.get());
|
||||
key = InternalBiomeAPI.biomeRegistry.getResourceKey(biome);
|
||||
} else {
|
||||
key = BuiltinRegistries.BIOME.getResourceKey(biome);
|
||||
}
|
||||
|
||||
return BuiltinRegistries.BIOME.getOrCreateHolder(BiomeAPI.getBiomeKey(biome));
|
||||
return getBiomeHolder(key.orElseThrow());
|
||||
}
|
||||
|
||||
public static Holder<Biome> getBiomeHolder(ResourceKey<Biome> biomeKey) {
|
||||
if (InternalBiomeAPI.biomeRegistry != null) {
|
||||
return InternalBiomeAPI.biomeRegistry.getOrCreateHolderOrThrow(biomeKey);
|
||||
}
|
||||
return BuiltinRegistries.BIOME.getOrCreateHolderOrThrow(biomeKey);
|
||||
}
|
||||
|
||||
public static Holder<Biome> getBiomeHolder(ResourceLocation biome) {
|
||||
if (InternalBiomeAPI.biomeRegistry != null) {
|
||||
return getBiomeHolder(InternalBiomeAPI.biomeRegistry.get(biome));
|
||||
}
|
||||
return getBiomeHolder(BuiltinRegistries.BIOME.get(biome));
|
||||
return getBiomeHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biome));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -459,7 +594,8 @@ public class BiomeAPI {
|
|||
* @return {@link BCLBiome} or {@code BiomeAPI.EMPTY_BIOME}.
|
||||
*/
|
||||
public static BCLBiome getBiome(ResourceLocation biomeID) {
|
||||
return ID_MAP.getOrDefault(biomeID, EMPTY_BIOME);
|
||||
if (biomeID == null) return BCLBiomeRegistry.EMPTY_BIOME;
|
||||
return BCLBiomeRegistry.getOrElseEmpty(biomeID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -489,30 +625,54 @@ public class BiomeAPI {
|
|||
* @return {@code true} if biome exists in API registry and {@code false} if not.
|
||||
*/
|
||||
public static boolean hasBiome(ResourceLocation biomeID) {
|
||||
return ID_MAP.containsKey(biomeID);
|
||||
return BCLBiomeRegistry.get(biomeID) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Holder<Biome> getFromRegistry(ResourceLocation key) {
|
||||
return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, key)).orElseThrow();
|
||||
public static Holder<Biome> getFromRegistry(ResourceLocation biomeID) {
|
||||
if (InternalBiomeAPI.biomeRegistry != null)
|
||||
return InternalBiomeAPI.biomeRegistry.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID))
|
||||
.orElseThrow();
|
||||
return getFromBuiltinRegistry(biomeID);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Holder<Biome> getFromRegistry(ResourceKey<Biome> key) {
|
||||
return BuiltinRegistries.BIOME.getOrCreateHolder(key);
|
||||
if (InternalBiomeAPI.biomeRegistry != null)
|
||||
return InternalBiomeAPI.biomeRegistry.getHolder(key).orElseThrow();
|
||||
return getFromBuiltinRegistry(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Holder<Biome> getFromBuiltinRegistry(ResourceLocation biomeID) {
|
||||
return BuiltinRegistries.BIOME.getHolder(ResourceKey.create(Registry.BIOME_REGISTRY, biomeID)).orElse(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Holder<Biome> getFromBuiltinRegistry(ResourceKey<Biome> key) {
|
||||
return BuiltinRegistries.BIOME.getHolder(key).orElse(null);
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean registryContains(ResourceKey<Biome> key) {
|
||||
if (InternalBiomeAPI.biomeRegistry != null)
|
||||
return InternalBiomeAPI.biomeRegistry.containsKey(key);
|
||||
return builtinRegistryContains(key);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Deprecated(forRemoval = true)
|
||||
public static boolean builtinRegistryContains(ResourceKey<Biome> key) {
|
||||
return BuiltinRegistries.BIOME.containsKey(key);
|
||||
}
|
||||
|
||||
public static boolean isDatapackBiome(ResourceLocation biomeID) {
|
||||
return getFromRegistry(biomeID) == null;
|
||||
return getFromBuiltinRegistry(biomeID) == null;
|
||||
}
|
||||
|
||||
public static boolean wasRegisteredAs(ResourceLocation biomeID, BiomeType dim) {
|
||||
if (BiomeType.BIOME_TYPE_MAP.containsKey(biomeID) && BiomeType.BIOME_TYPE_MAP.get(biomeID).is(dim)) return true;
|
||||
BCLBiome biome = getBiome(biomeID);
|
||||
if (biome != null && biome != BiomeAPI.EMPTY_BIOME && biome.getParentBiome() != null) {
|
||||
return wasRegisteredAs(biome.getParentBiome().getID(), dim);
|
||||
}
|
||||
return false;
|
||||
if (BCLBiomeRegistry.EMPTY_BIOME.getID().equals(biomeID))
|
||||
return false;
|
||||
return BCLBiomeRegistry.getOrElseEmpty(biomeID).getIntendedType().is(dim);
|
||||
}
|
||||
|
||||
public static boolean wasRegisteredAsNetherBiome(ResourceLocation biomeID) {
|
||||
|
@ -531,6 +691,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.
|
||||
*
|
||||
|
@ -628,16 +796,16 @@ public class BiomeAPI {
|
|||
}
|
||||
|
||||
static void sortBiomeFeatures(Biome biome) {
|
||||
BiomeGenerationSettings settings = biome.getGenerationSettings();
|
||||
BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings;
|
||||
List<HolderSet<PlacedFeature>> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
final int size = featureList.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
List<Holder<PlacedFeature>> features = getFeaturesListCopy(featureList, i);
|
||||
sortFeatures(features);
|
||||
featureList.set(i, HolderSet.direct(features));
|
||||
}
|
||||
accessor.bclib_setFeatures(featureList);
|
||||
// BiomeGenerationSettings settings = biome.getGenerationSettings();
|
||||
// BiomeGenerationSettingsAccessor accessor = (BiomeGenerationSettingsAccessor) settings;
|
||||
// List<HolderSet<PlacedFeature>> featureList = CollectionsUtil.getMutable(accessor.bclib_getFeatures());
|
||||
// final int size = featureList.size();
|
||||
// for (int i = 0; i < size; i++) {
|
||||
// List<Holder<PlacedFeature>> features = getFeaturesListCopy(featureList, i);
|
||||
// sortFeatures(features);
|
||||
// featureList.set(i, HolderSet.direct(features));
|
||||
// }
|
||||
// accessor.bclib_setFeatures(featureList);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -840,4 +1008,86 @@ 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 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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLBiome registerEndBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
registerBiome(bclBiome, BiomeType.END);
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLBiome registerCenterBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
|
||||
registerBiome(bclBiome, BiomeType.END_CENTER);
|
||||
return bclBiome;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.biomes;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.util.KeyDispatchDataCodec;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface BiomeData {
|
||||
Codec<BCLBiome> CODEC = BCLBiomeRegistry
|
||||
.BIOME_CODECS
|
||||
.byNameCodec()
|
||||
.dispatch(b -> b.codec().codec(), Function.identity());
|
||||
|
||||
KeyDispatchDataCodec<? extends BCLBiome> codec();
|
||||
}
|
|
@ -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);
|
||||
|
@ -86,7 +108,7 @@ public class InternalBiomeAPI {
|
|||
BIOMES_TO_SORT.forEach(id -> {
|
||||
Biome b = biomeRegistry.get(id);
|
||||
if (b != null) {
|
||||
BCLib.LOGGER.info("Sorting Features in Biome: " + id + "(" + b + ")");
|
||||
BCLib.LOGGER.info("Found non fabric/bclib Biome: " + id + "(" + b + ")");
|
||||
BiomeAPI.sortBiomeFeatures(b);
|
||||
} else {
|
||||
BCLib.LOGGER.info("Unknown Biome: " + id);
|
||||
|
@ -143,21 +165,17 @@ public class InternalBiomeAPI {
|
|||
public static void _runBiomeTagAdders() {
|
||||
for (var mod : TAG_ADDERS.entrySet()) {
|
||||
Stream<ResourceLocation> s = null;
|
||||
if (mod.getKey() == Level.NETHER) s = BiomeAPI.BiomeType.BIOME_TYPE_MAP.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue()
|
||||
.is(BiomeAPI.BiomeType.NETHER))
|
||||
.map(e -> e.getKey());
|
||||
else if (mod.getKey() == Level.END) s = BiomeAPI.BiomeType.BIOME_TYPE_MAP.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().is(
|
||||
BiomeAPI.BiomeType.END))
|
||||
.map(e -> e.getKey());
|
||||
if (mod.getKey() == Level.NETHER)
|
||||
s = BCLBiomeRegistry.getAll(BiomeAPI.BiomeType.NETHER).map(k -> k.location());
|
||||
else if (mod.getKey() == Level.END)
|
||||
s = BCLBiomeRegistry.getAll(BiomeAPI.BiomeType.END).map(k -> k.location());
|
||||
if (s != null) {
|
||||
s.forEach(id -> {
|
||||
Holder<Biome> biomeHolder = BiomeAPI.getBiomeHolder(id);
|
||||
if (biomeHolder.isBound()) {
|
||||
Holder<Biome> biomeHolder = BiomeAPI.getFromRegistry(id);
|
||||
if (biomeHolder != null && biomeHolder.isBound()) {
|
||||
mod.getValue().forEach(c -> c.accept(id, biomeHolder));
|
||||
} else {
|
||||
BCLib.LOGGER.info("No Holder for " + id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -246,6 +264,93 @@ 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 biomeKey The source biome to wrap
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome wrapNativeBiome(ResourceKey<Biome> biomeKey, BiomeAPI.BiomeType type) {
|
||||
return wrapNativeBiome(biomeKey, -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 biomeKey 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> biomeKey, float genChance, BiomeAPI.BiomeType type) {
|
||||
return wrapNativeBiome(
|
||||
biomeKey,
|
||||
genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build(),
|
||||
type
|
||||
);
|
||||
}
|
||||
|
||||
public static BCLBiome wrapNativeBiome(
|
||||
ResourceKey<Biome> biomeKey,
|
||||
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(biomeKey, 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 biomeKey The source biome to wrap
|
||||
* @param setings the {@link VanillaBiomeSettings} to use
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
private static BCLBiome wrapNativeBiome(
|
||||
ResourceKey<Biome> biomeKey,
|
||||
VanillaBiomeSettings setings,
|
||||
BiomeAPI.BiomeType type
|
||||
) {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biomeKey.location());
|
||||
if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
bclBiome = new BCLBiome(biomeKey, setings);
|
||||
bclBiome._setIntendedType(type);
|
||||
}
|
||||
|
||||
BiomeAPI.registerBiome(bclBiome);
|
||||
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}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biome);
|
||||
if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
bclBiome = new BCLBiome(
|
||||
biome,
|
||||
genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
|
||||
);
|
||||
}
|
||||
|
||||
BiomeAPI.registerBiome(bclBiome, type, null);
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
static {
|
||||
DynamicRegistrySetupCallback.EVENT.register(registryManager -> {
|
||||
Optional<? extends Registry<Biome>> oBiomeRegistry = registryManager.registry(Registry.BIOME_REGISTRY);
|
||||
|
@ -253,11 +358,21 @@ public class InternalBiomeAPI {
|
|||
.event(oBiomeRegistry.get())
|
||||
.register((rawId, id, biome) -> {
|
||||
BCLBiome b = BiomeAPI.getBiome(id);
|
||||
if (!"minecraft".equals(id.getNamespace()) && (b == null || b == BiomeAPI.EMPTY_BIOME)) {
|
||||
if (!"minecraft".equals(id.getNamespace()) && (b == null || b == BCLBiomeRegistry.EMPTY_BIOME)) {
|
||||
//BCLib.LOGGER.info(" #### " + rawId + ", " + biome + ", " + id);
|
||||
BIOMES_TO_SORT.add(id);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean registryContainsBound(ResourceKey<Biome> key) {
|
||||
Registry<Biome> reg = biomeRegistry;
|
||||
if (reg == null) reg = BuiltinRegistries.BIOME;
|
||||
|
||||
if (reg.containsKey(key)) {
|
||||
return reg.getOrCreateHolderOrThrow(key).isBound();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.util.List;
|
|||
/**
|
||||
* @deprecated Please use {@link org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class TemplateFeatureConfig extends org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig {
|
||||
|
||||
public TemplateFeatureConfig(ResourceLocation location, int offsetY, StructurePlacementType type) {
|
||||
|
|
|
@ -11,8 +11,8 @@ import net.minecraft.world.level.levelgen.feature.Feature;
|
|||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
|
||||
public abstract class DefaultFeature extends Feature<NoneFeatureConfiguration> {
|
||||
protected static final BlockState AIR = Blocks.AIR.defaultBlockState();
|
||||
protected static final BlockState WATER = Blocks.WATER.defaultBlockState();
|
||||
public static final BlockState AIR = Blocks.AIR.defaultBlockState();
|
||||
public static final BlockState WATER = Blocks.WATER.defaultBlockState();
|
||||
|
||||
public DefaultFeature() {
|
||||
super(NoneFeatureConfiguration.CODEC);
|
||||
|
|
|
@ -1,14 +1,24 @@
|
|||
package org.betterx.bclib.api.v2.levelgen.structures;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.util.BlocksHelper;
|
||||
import org.betterx.bclib.util.MHelper;
|
||||
import org.betterx.bclib.util.StructureErode;
|
||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.StructureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.levelgen.structure.TemplateStructurePiece;
|
||||
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
|
||||
|
@ -21,6 +31,8 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
|||
import java.util.Random;
|
||||
|
||||
public class TemplatePiece extends TemplateStructurePiece {
|
||||
private final int erosion;
|
||||
private final boolean cover;
|
||||
public static final StructurePieceType INSTANCE = setTemplatePieceId(
|
||||
TemplatePiece::new,
|
||||
"template_piece"
|
||||
|
@ -42,7 +54,6 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
public static void ensureStaticInitialization() {
|
||||
}
|
||||
|
||||
|
||||
public TemplatePiece(
|
||||
StructureManager structureTemplateManager,
|
||||
ResourceLocation resourceLocation,
|
||||
|
@ -50,6 +61,19 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
Rotation rotation,
|
||||
Mirror mirror,
|
||||
BlockPos halfSize
|
||||
) {
|
||||
this(structureTemplateManager, resourceLocation, centerPos, rotation, mirror, halfSize, 0, false);
|
||||
}
|
||||
|
||||
public TemplatePiece(
|
||||
StructureTemplateManager structureTemplateManager,
|
||||
ResourceLocation resourceLocation,
|
||||
BlockPos centerPos,
|
||||
Rotation rotation,
|
||||
Mirror mirror,
|
||||
BlockPos halfSize,
|
||||
int erosion,
|
||||
boolean cover
|
||||
) {
|
||||
super(
|
||||
INSTANCE,
|
||||
|
@ -60,6 +84,8 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
makeSettings(rotation, mirror, halfSize),
|
||||
shiftPos(rotation, mirror, halfSize, centerPos)
|
||||
);
|
||||
this.erosion = erosion;
|
||||
this.cover = cover;
|
||||
}
|
||||
|
||||
public TemplatePiece(StructureManager structureTemplateManager, CompoundTag compoundTag) {
|
||||
|
@ -69,6 +95,15 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
structureTemplateManager,
|
||||
(ResourceLocation resourceLocation) -> makeSettings(compoundTag)
|
||||
);
|
||||
if (compoundTag.contains("E"))
|
||||
this.erosion = compoundTag.getInt("E");
|
||||
else
|
||||
this.erosion = 0;
|
||||
|
||||
if (compoundTag.contains("C"))
|
||||
this.cover = compoundTag.getBoolean("C");
|
||||
else
|
||||
this.cover = true;
|
||||
}
|
||||
|
||||
private static BlockPos shiftPos(
|
||||
|
@ -108,6 +143,8 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
tag.putInt("RX", this.placeSettings.getRotationPivot().getX());
|
||||
tag.putInt("RY", this.placeSettings.getRotationPivot().getY());
|
||||
tag.putInt("RZ", this.placeSettings.getRotationPivot().getZ());
|
||||
tag.putInt("E", this.erosion);
|
||||
tag.putBoolean("C", this.cover);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -120,4 +157,54 @@ public class TemplatePiece extends TemplateStructurePiece {
|
|||
) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcess(
|
||||
WorldGenLevel world,
|
||||
StructureManager structureManager,
|
||||
ChunkGenerator chunkGenerator,
|
||||
RandomSource random,
|
||||
BoundingBox boundingBox,
|
||||
ChunkPos chunkPos,
|
||||
BlockPos blockPos
|
||||
) {
|
||||
BlockState coverState = null;
|
||||
if (cover) {
|
||||
BlockPos.MutableBlockPos mPos = new BlockPos(
|
||||
this.boundingBox.minX() - 1,
|
||||
blockPos.getY(),
|
||||
this.boundingBox.minZ() - 1
|
||||
).mutable();
|
||||
if (BlocksHelper.findOnSurroundingSurface(
|
||||
world,
|
||||
mPos,
|
||||
Direction.DOWN,
|
||||
8,
|
||||
s -> s.is(CommonBlockTags.TERRAIN)
|
||||
)) {
|
||||
mPos.move(Direction.DOWN);
|
||||
coverState = world.getBlockState(mPos);
|
||||
}
|
||||
}
|
||||
super.postProcess(world, structureManager, chunkGenerator, random, boundingBox, chunkPos, blockPos);
|
||||
BoundingBox bounds = BoundingBox.fromCorners(new Vec3i(
|
||||
boundingBox.minX(),
|
||||
this.boundingBox.minY(),
|
||||
boundingBox.minZ()
|
||||
), new Vec3i(boundingBox.maxX(), this.boundingBox.maxY(), boundingBox.maxZ()));
|
||||
|
||||
if (erosion > 0) {
|
||||
int x1 = MHelper.min(bounds.maxX(), this.boundingBox.maxX());
|
||||
int x0 = MHelper.max(bounds.minX(), this.boundingBox.minX());
|
||||
int z1 = MHelper.min(bounds.maxZ(), this.boundingBox.maxZ());
|
||||
int z0 = MHelper.max(bounds.minZ(), this.boundingBox.minZ());
|
||||
bounds = BoundingBox.fromCorners(new Vec3i(x0, bounds.minY(), z0), new Vec3i(x1, bounds.maxY(), z1));
|
||||
StructureErode.erode(world, bounds, erosion, random);
|
||||
}
|
||||
|
||||
if (cover) {
|
||||
//System.out.println("CoverState:" + coverState + ", " + blockPos + " " + boundingBox.getCenter());
|
||||
StructureErode.cover(world, bounds, random, coverState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import java.util.Optional;
|
|||
import java.util.Random;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.BiPredicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class TemplateStructure extends StructureFeature {
|
||||
protected final List<Config> configs;
|
||||
|
@ -84,6 +83,14 @@ public abstract class TemplateStructure extends StructureFeature {
|
|||
return (state == null || state.is(Blocks.AIR)) && before.getMaterial().isSolid();
|
||||
}
|
||||
|
||||
protected int erosion(RandomSource rnd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean cover(RandomSource rnd) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<GenerationStub> findGenerationPoint(GenerationContext ctx) {
|
||||
WorldGenerationContext worldGenerationContext = new WorldGenerationContext(
|
||||
|
@ -153,8 +160,7 @@ public abstract class TemplateStructure extends StructureFeature {
|
|||
blockPos.getZ(),
|
||||
ctx.heightAccessor(),
|
||||
ctx.randomState()
|
||||
))
|
||||
.collect(Collectors.toList());
|
||||
)).toList();
|
||||
|
||||
int y = noiseColumns
|
||||
.stream()
|
||||
|
@ -185,6 +191,8 @@ public abstract class TemplateStructure extends StructureFeature {
|
|||
|
||||
centerPos.setY(y - (searchStep == 1 ? 0 : (structureTemplate.getSize(Rotation.NONE).getY())));
|
||||
|
||||
int erosion = erosion(ctx.random());
|
||||
boolean cover = cover(ctx.random());
|
||||
// if (!structure.canGenerate(ctx.chunkGenerator()., centerPos))
|
||||
return Optional.of(new GenerationStub(
|
||||
centerPos,
|
||||
|
@ -200,7 +208,9 @@ public abstract class TemplateStructure extends StructureFeature {
|
|||
),
|
||||
rotation,
|
||||
mirror,
|
||||
halfSize
|
||||
halfSize,
|
||||
erosion,
|
||||
cover
|
||||
))
|
||||
));
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package org.betterx.bclib.api.v3.levelgen.features.features;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeature;
|
||||
import org.betterx.bclib.api.v2.levelgen.features.BCLFeatureBuilder;
|
||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureNBT;
|
||||
import org.betterx.bclib.api.v2.levelgen.structures.StructureWorldNBT;
|
||||
import org.betterx.bclib.api.v3.levelgen.features.config.TemplateFeatureConfig;
|
||||
|
@ -15,51 +13,11 @@ import net.minecraft.world.level.levelgen.feature.FeaturePlaceContext;
|
|||
import java.util.Random;
|
||||
|
||||
public class TemplateFeature<FC extends TemplateFeatureConfig> extends Feature<FC> {
|
||||
|
||||
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegisterRare(
|
||||
ResourceLocation location,
|
||||
TemplateFeatureConfig configuration,
|
||||
int onceEveryChunk
|
||||
) {
|
||||
|
||||
|
||||
return BCLFeatureBuilder
|
||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||
.onceEvery(onceEveryChunk) //discard neighboring chunks
|
||||
.count(16) //try 16 placements in chunk
|
||||
.squarePlacement() //randomize x/z in chunk
|
||||
.randomHeight10FromFloorCeil() //randomize height 10 above and 10 below max vertical
|
||||
.findSolidFloor(12) //cast downward ray to find solid surface
|
||||
.isEmptyAbove4() //make sure we have 4 free blocks above
|
||||
.onlyInBiome() //ensure that we still are in the correct biome
|
||||
|
||||
.buildAndRegister(configuration);
|
||||
}
|
||||
|
||||
public static <T extends TemplateFeatureConfig> BCLFeature createAndRegister(
|
||||
ResourceLocation location,
|
||||
TemplateFeatureConfig configuration,
|
||||
int count
|
||||
) {
|
||||
return BCLFeatureBuilder
|
||||
.start(location, org.betterx.bclib.api.v3.levelgen.features.BCLFeature.TEMPLATE)
|
||||
.decoration(GenerationStep.Decoration.SURFACE_STRUCTURES)
|
||||
.count(count)
|
||||
.squarePlacement()
|
||||
.randomHeight10FromFloorCeil()
|
||||
.findSolidFloor(12) //cast downward ray to find solid surface
|
||||
.isEmptyAbove4()
|
||||
.onlyInBiome()
|
||||
.buildAndRegister(configuration);
|
||||
}
|
||||
|
||||
public TemplateFeature(Codec<FC> codec) {
|
||||
super(codec);
|
||||
}
|
||||
|
||||
protected StructureWorldNBT randomStructure(TemplateFeatureConfig cfg, Random random) {
|
||||
|
||||
if (cfg.structures.size() > 1) {
|
||||
final float chanceSum = cfg.structures.parallelStream().map(c -> c.chance).reduce(0.0f, (p, c) -> p + c);
|
||||
float rnd = random.nextFloat() * chanceSum;
|
||||
|
|
|
@ -6,8 +6,8 @@ import org.betterx.bclib.api.v2.dataexchange.DataExchangeAPI;
|
|||
import org.betterx.bclib.client.models.CustomModelBakery;
|
||||
import org.betterx.bclib.config.Configs;
|
||||
import org.betterx.bclib.registry.BaseBlockEntityRenders;
|
||||
import org.betterx.bclib.registry.PresetsRegistryClient;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.client.WorldsTogetherClient;
|
||||
|
||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
|
@ -31,7 +31,7 @@ public class BCLibClient implements ClientModInitializer, ModelResourceProvider,
|
|||
ModelLoadingRegistry.INSTANCE.registerResourceProvider(rm -> this);
|
||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(rm -> this);
|
||||
|
||||
WorldsTogetherClient.onInitializeClient();
|
||||
PresetsRegistryClient.onLoad();
|
||||
WorldsTogether.SURPRESS_EXPERIMENTAL_DIALOG = Configs.CLIENT_CONFIG.suppressExperimentalDialog();
|
||||
//dumpDatapack();
|
||||
}
|
||||
|
|
|
@ -185,7 +185,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);
|
||||
|
@ -201,7 +205,10 @@ public class WorldSetupScreen extends BCLibScreen {
|
|||
BCLNetherBiomeSourceConfig netherConfig = new BCLNetherBiomeSourceConfig(
|
||||
netherLegacy.isChecked()
|
||||
? BCLNetherBiomeSourceConfig.NetherBiomeMapType.SQUARE
|
||||
: BCLNetherBiomeSourceConfig.NetherBiomeMapType.HEX
|
||||
: BCLNetherBiomeSourceConfig.NetherBiomeMapType.HEX,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.biomeSize,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.biomeSizeVertical,
|
||||
BCLNetherBiomeSourceConfig.DEFAULT.useVerticalBiomes
|
||||
);
|
||||
|
||||
ChunkGenerator netherGenerator = betterxDimensions.get(LevelStem.NETHER);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.betterx.bclib.client.render;
|
||||
|
||||
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.bclib.util.BackgroundInfo;
|
||||
|
@ -116,7 +117,7 @@ public class CustomFogRenderer {
|
|||
|
||||
private static boolean shouldIgnore(Level level, int x, int y, int z) {
|
||||
Biome biome = level.getBiome(MUT_POS.set(x, y, z)).value();
|
||||
return BiomeAPI.getRenderBiome(biome) == BiomeAPI.EMPTY_BIOME;
|
||||
return BiomeAPI.getRenderBiome(biome) == BCLBiomeRegistry.EMPTY_BIOME;
|
||||
}
|
||||
|
||||
private static float getFogDensityI(Level level, int x, int y, int z) {
|
||||
|
|
111
src/main/java/org/betterx/bclib/config/BiomesConfig.java
Normal file
111
src/main/java/org/betterx/bclib/config/BiomesConfig.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
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 List<String> getExcludeMatching(BiomeAPI.BiomeType type) {
|
||||
return getBiomeExcludeMap().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;
|
||||
}
|
||||
}
|
|
@ -5,8 +5,6 @@ import org.betterx.bclib.BCLib;
|
|||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class Configs {
|
||||
// Client and Server-Config must be the first entries. They are not part of the Auto-Sync process
|
||||
// But will be needed by other Auto-Sync Config-Files
|
||||
|
@ -18,7 +16,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";
|
||||
|
||||
|
@ -28,23 +26,4 @@ public class Configs {
|
|||
GENERATOR_CONFIG.saveChanges();
|
||||
BIOMES_CONFIG.saveChanges();
|
||||
}
|
||||
|
||||
static {
|
||||
BIOMES_CONFIG.keeper.registerEntry(
|
||||
new ConfigKey("end_land_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
|
||||
);
|
||||
BIOMES_CONFIG.keeper.registerEntry(
|
||||
new ConfigKey("end_void_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
|
||||
);
|
||||
BIOMES_CONFIG.keeper.registerEntry(
|
||||
new ConfigKey("nether_biomes", "force_include"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
|
||||
);
|
||||
BIOMES_CONFIG.keeper.registerEntry(
|
||||
new ConfigKey("nether_biomes", "force_exclude"),
|
||||
new ConfigKeeper.StringArrayEntry(Collections.EMPTY_LIST)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,11 @@ public class ServerConfig extends NamedPathConfig {
|
|||
"excludeMods",
|
||||
AutoSync.SYNC_CATEGORY
|
||||
);
|
||||
public static final ConfigToken<Boolean> FORCE_BETTERX_PRESET = ConfigToken.Boolean(
|
||||
true,
|
||||
"forceBetterXPreset",
|
||||
AutoSync.SYNC_CATEGORY
|
||||
);
|
||||
|
||||
|
||||
public ServerConfig() {
|
||||
|
@ -85,4 +90,8 @@ public class ServerConfig extends NamedPathConfig {
|
|||
return get(SEND_ALL_MOD_INFO) /*&& isAllowingAutoSync()*/;
|
||||
}
|
||||
|
||||
public boolean forceBetterXPreset() {
|
||||
return get(FORCE_BETTERX_PRESET);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
|
@ -0,0 +1,40 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.WritableRegistry;
|
||||
import net.minecraft.data.BuiltinRegistries;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(BuiltinRegistries.class)
|
||||
public abstract class BuiltinRegistriesMixin {
|
||||
@Shadow
|
||||
protected static <T, R extends WritableRegistry<T>> R internalRegister(
|
||||
ResourceKey<? extends Registry<T>> resourceKey,
|
||||
R writableRegistry,
|
||||
BuiltinRegistries.RegistryBootstrap<T> registryBootstrap,
|
||||
Lifecycle lifecycle
|
||||
) {
|
||||
throw new RuntimeException("Shadowed Call");
|
||||
}
|
||||
|
||||
//this needs to be added BEFORE the WORLD_PRESET-Registry. Otherwise decoding will fail!
|
||||
@Inject(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/BuiltinRegistries;registerSimple(Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/data/BuiltinRegistries$RegistryBootstrap;)Lnet/minecraft/core/Registry;", ordinal = 0))
|
||||
private static void bcl_registerBuiltin(CallbackInfo ci) {
|
||||
BCLBiomeRegistry.BUILTIN_BCL_BIOMES = internalRegister(
|
||||
BCLBiomeRegistry.BCL_BIOMES_REGISTRY,
|
||||
(MappedRegistry) BCLBiomeRegistry.BUILTIN_BCL_BIOMES,
|
||||
BCLBiomeRegistry::bootstrap,
|
||||
Lifecycle.stable()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import org.betterx.worlds.together.worldPreset.WorldPresets;
|
||||
|
||||
import net.minecraft.server.dedicated.DedicatedServerProperties;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(DedicatedServerProperties.class)
|
||||
public class DedicatedServerPropertiesMixin {
|
||||
//Make sure the default server properties use our Default World Preset
|
||||
@ModifyArg(method = "<init>", index = 3, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServerProperties$WorldGenProperties;<init>(Ljava/lang/String;Lcom/google/gson/JsonObject;ZLjava/lang/String;)V"))
|
||||
private String bcl_init(String levelType) {
|
||||
return WorldPresets.getDEFAULT().location().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiomeRegistry;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeData;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mixin(RegistryAccess.class)
|
||||
public interface RegistryAccessMixin {
|
||||
|
||||
@ModifyArg(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/Util;make(Ljava/util/function/Supplier;)Ljava/lang/Object;"))
|
||||
private static Supplier<ImmutableMap<ResourceKey<Registry<?>>, RegistryAccess.RegistryData<?>>> together_addRegistry(
|
||||
Supplier<ImmutableMap<ResourceKey<Registry<?>>, RegistryAccess.RegistryData<?>>> supplier
|
||||
) {
|
||||
return () -> {
|
||||
ImmutableMap.Builder<ResourceKey<Registry<?>>, RegistryAccess.RegistryData<?>> builder = ImmutableMap.builder();
|
||||
//Make sure this gets added before WORLD_PRESETS
|
||||
put(builder, BCLBiomeRegistry.BCL_BIOMES_REGISTRY, BiomeData.CODEC);
|
||||
|
||||
Map<ResourceKey<Registry<?>>, RegistryAccess.RegistryData<?>> res = supplier.get();
|
||||
builder.putAll(res);
|
||||
|
||||
return builder.build();
|
||||
};
|
||||
}
|
||||
|
||||
@Shadow
|
||||
static <E> void put(
|
||||
ImmutableMap.Builder<ResourceKey<Registry<?>>, RegistryAccess.RegistryData<?>> builder,
|
||||
ResourceKey<? extends Registry<E>> resourceKey,
|
||||
Codec<E> codec
|
||||
) {
|
||||
throw new RuntimeException("Shadowed Call");
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package org.betterx.bclib.mixin.common;
|
||||
|
||||
import org.betterx.bclib.api.v2.LifeCycleAPI;
|
||||
import org.betterx.bclib.api.v2.generator.BCLBiomeSource;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithSeed;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
@ -12,6 +13,7 @@ import net.minecraft.util.profiling.ProfilerFiller;
|
|||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess;
|
||||
import net.minecraft.world.level.storage.ServerLevelData;
|
||||
import net.minecraft.world.level.storage.WritableLevelData;
|
||||
|
@ -73,10 +75,15 @@ public abstract class ServerLevelMixin extends Level {
|
|||
bl2
|
||||
);
|
||||
|
||||
if (levelStem.generator().getBiomeSource() instanceof BCLBiomeSource source) {
|
||||
if (levelStem.generator().getBiomeSource() instanceof BiomeSourceWithSeed source) {
|
||||
source.setSeed(level.getSeed());
|
||||
}
|
||||
|
||||
if (levelStem.generator().getBiomeSource() instanceof BiomeSourceWithNoiseRelatedSettings bcl
|
||||
&& levelStem.generator() instanceof NoiseBasedChunkGenerator noiseGenerator) {
|
||||
bcl.onLoadGeneratorSettings(noiseGenerator.generatorSettings().value());
|
||||
}
|
||||
|
||||
if (bclib_lastWorld != null && bclib_lastWorld.equals(levelStorageAccess.getLevelId())) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import org.betterx.bclib.BCLib;
|
|||
import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
|
||||
import org.betterx.bclib.api.v2.levelgen.LevelGenUtil;
|
||||
import org.betterx.worlds.together.entrypoints.WorldPresetBootstrap;
|
||||
import org.betterx.worlds.together.levelgen.WorldGenUtil;
|
||||
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPreset;
|
||||
|
@ -14,11 +15,11 @@ import net.minecraft.world.level.dimension.LevelStem;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
public class PresetsRegistry {
|
||||
public class PresetsRegistry implements WorldPresetBootstrap {
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD;
|
||||
public static ResourceKey<WorldPreset> BCL_WORLD_17;
|
||||
|
||||
public static void onLoad() {
|
||||
public void bootstrapWorldPresets() {
|
||||
BCL_WORLD =
|
||||
WorldPresets.register(
|
||||
BCLib.makeID("normal"),
|
||||
|
|
|
@ -3,10 +3,20 @@ package org.betterx.bclib.util;
|
|||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link org.betterx.worlds.together.util.Logger} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public final class Logger {
|
||||
private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger();
|
||||
private final String modPref;
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link org.betterx.worlds.together.util.Logger#Logger(String)} instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public Logger(String modID) {
|
||||
this.modPref = "[" + modID + "] ";
|
||||
}
|
||||
|
|
|
@ -4,16 +4,75 @@ import com.mojang.math.Vector3f;
|
|||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.world.level.levelgen.LegacyRandomSource;
|
||||
import net.minecraft.world.level.levelgen.RandomSource;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
public class MHelper {
|
||||
static class ThreadLocalRandomSource implements RandomSource {
|
||||
ThreadLocalRandomSource(long seed) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public RandomSource fork() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PositionalRandomFactory forkPositional() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSeed(long l) {
|
||||
ThreadLocalRandom.current().setSeed(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt() {
|
||||
return ThreadLocalRandom.current().nextInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int nextInt(int i) {
|
||||
return ThreadLocalRandom.current().nextInt(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long nextLong() {
|
||||
return ThreadLocalRandom.current().nextLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean nextBoolean() {
|
||||
return ThreadLocalRandom.current().nextBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float nextFloat() {
|
||||
return ThreadLocalRandom.current().nextFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextDouble() {
|
||||
return ThreadLocalRandom.current().nextDouble();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double nextGaussian() {
|
||||
return ThreadLocalRandom.current().nextGaussian();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Vec3i[] RANDOM_OFFSETS = new Vec3i[3 * 3 * 3 - 1];
|
||||
private static final float RAD_TO_DEG = 57.295779513082320876798154814105F;
|
||||
public static final float PHI = (float) (Math.PI * (3 - Math.sqrt(5)));
|
||||
public static final float PI2 = (float) (Math.PI * 2);
|
||||
public static final Random RANDOM = new Random();
|
||||
public static final RandomSource RANDOM_SOURCE = new LegacyRandomSource(RANDOM.nextLong());
|
||||
public static final RandomSource RANDOM_SOURCE = new ThreadLocalRandomSource(RANDOM.nextLong());
|
||||
|
||||
public static int randRange(int min, int max, Random random) {
|
||||
return min + random.nextInt(max - min + 1);
|
||||
|
|
|
@ -1,8 +1,20 @@
|
|||
package org.betterx.bclib.util;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class Pair<A, B> {
|
||||
public static <A, B> Codec<Pair<A, B>> pairCodec(Codec<A> a, Codec<B> b, String first, String second) {
|
||||
return RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
a.fieldOf(first).forGetter(o -> o.first),
|
||||
b.fieldOf(second).forGetter(o -> o.second)
|
||||
)
|
||||
.apply(instance, Pair::new));
|
||||
}
|
||||
|
||||
public final A first;
|
||||
public final B second;
|
||||
|
||||
|
|
277
src/main/java/org/betterx/bclib/util/StructureErode.java
Normal file
277
src/main/java/org/betterx/bclib/util/StructureErode.java
Normal file
|
@ -0,0 +1,277 @@
|
|||
package org.betterx.bclib.util;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.worlds.together.tag.v3.CommonBlockTags;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.BlockPos.MutableBlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class StructureErode {
|
||||
private static final Direction[] DIR = BlocksHelper.makeHorizontal();
|
||||
|
||||
public static void erode(WorldGenLevel world, BoundingBox bounds, int iterations, RandomSource random) {
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
boolean canDestruct = true;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
boolean ignore = ignore(state, world, mut);
|
||||
if (canDestruct && BlocksHelper.isInvulnerable(
|
||||
state,
|
||||
world,
|
||||
mut
|
||||
) && random.nextInt(8) == 0 && world.isEmptyBlock(
|
||||
mut.below(2))) {
|
||||
int r = MHelper.randRange(1, 4, random);
|
||||
int cx = mut.getX();
|
||||
int cy = mut.getY();
|
||||
int cz = mut.getZ();
|
||||
int x1 = cx - r;
|
||||
int y1 = cy - r;
|
||||
int z1 = cz - r;
|
||||
int x2 = cx + r;
|
||||
int y2 = cy + r;
|
||||
int z2 = cz + r;
|
||||
for (int px = x1; px <= x2; px++) {
|
||||
int dx = px - cx;
|
||||
dx *= dx;
|
||||
mut.setX(px);
|
||||
for (int py = y1; py <= y2; py++) {
|
||||
int dy = py - cy;
|
||||
dy *= dy;
|
||||
mut.setY(py);
|
||||
for (int pz = z1; pz <= z2; pz++) {
|
||||
int dz = pz - cz;
|
||||
dz *= dz;
|
||||
mut.setZ(pz);
|
||||
if (dx + dy + dz <= r && BlocksHelper.isInvulnerable(
|
||||
world.getBlockState(mut),
|
||||
world,
|
||||
mut
|
||||
)) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mut.setX(cx);
|
||||
mut.setY(cy);
|
||||
mut.setZ(cz);
|
||||
canDestruct = false;
|
||||
continue;
|
||||
} else if (ignore) {
|
||||
continue;
|
||||
}
|
||||
if (!state.isAir() && random.nextBoolean()) {
|
||||
MHelper.shuffle(DIR, random);
|
||||
for (Direction dir : DIR) {
|
||||
if (world.isEmptyBlock(mut.relative(dir)) && world.isEmptyBlock(mut.below()
|
||||
.relative(dir))) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
mut.move(dir).move(Direction.DOWN);
|
||||
for (int py = mut.getY(); y >= bounds.minY() - 10; y--) {
|
||||
mut.setY(py - 1);
|
||||
if (!world.isEmptyBlock(mut)) {
|
||||
mut.setY(py);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (random.nextInt(8) == 0 && !BlocksHelper.isInvulnerable(
|
||||
world.getBlockState(mut.above()),
|
||||
world,
|
||||
mut
|
||||
)) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (!ignore(state, world, mut) && world.isEmptyBlock(mut.below())) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
for (int py = mut.getY(); py >= bounds.minY() - 10; py--) {
|
||||
mut.setY(py - 1);
|
||||
if (!world.isEmptyBlock(mut)) {
|
||||
mut.setY(py);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void erodeIntense(WorldGenLevel world, BoundingBox bounds, RandomSource random) {
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
MutableBlockPos mut2 = new MutableBlockPos();
|
||||
int minY = bounds.minY() - 10;
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (!ignore(state, world, mut)) {
|
||||
if (random.nextInt(6) == 0) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
if (random.nextBoolean()) {
|
||||
int px = MHelper.floor(random.nextGaussian() * 2 + x + 0.5);
|
||||
int pz = MHelper.floor(random.nextGaussian() * 2 + z + 0.5);
|
||||
mut2.set(px, y, pz);
|
||||
while (world.getBlockState(mut2).getMaterial().isReplaceable() && mut2.getY() > minY) {
|
||||
mut2.setY(mut2.getY() - 1);
|
||||
}
|
||||
if (!world.getBlockState(mut2).isAir() && state.canSurvive(world, mut2)) {
|
||||
mut2.setY(mut2.getY() + 1);
|
||||
BlocksHelper.setWithoutUpdate(world, mut2, state);
|
||||
}
|
||||
}
|
||||
} else if (random.nextInt(8) == 0) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drop(world, bounds);
|
||||
}
|
||||
|
||||
private static void drop(WorldGenLevel world, BoundingBox bounds) {
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
|
||||
Set<BlockPos> blocks = Sets.newHashSet();
|
||||
Set<BlockPos> edge = Sets.newHashSet();
|
||||
Set<BlockPos> add = Sets.newHashSet();
|
||||
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
for (int y = bounds.minY(); y <= bounds.maxY(); y++) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (!ignore(state, world, mut) && isTerrainNear(world, mut)) {
|
||||
edge.add(mut.immutable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (edge.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (!edge.isEmpty()) {
|
||||
for (BlockPos center : edge) {
|
||||
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
||||
BlockState state = world.getBlockState(center);
|
||||
if (state.isCollisionShapeFullBlock(world, center)) {
|
||||
mut.set(center).move(dir);
|
||||
if (bounds.isInside(mut)) {
|
||||
state = world.getBlockState(mut);
|
||||
if (!ignore(state, world, mut) && !blocks.contains(mut)) {
|
||||
add.add(mut.immutable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blocks.addAll(edge);
|
||||
edge.clear();
|
||||
edge.addAll(add);
|
||||
add.clear();
|
||||
}
|
||||
|
||||
int minY = bounds.minY() - 10;
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
for (int y = bounds.minY(); y <= bounds.maxY(); y++) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (!ignore(state, world, mut) && !blocks.contains(mut)) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, Blocks.AIR);
|
||||
while (world.getBlockState(mut).getMaterial().isReplaceable() && mut.getY() > minY) {
|
||||
mut.setY(mut.getY() - 1);
|
||||
}
|
||||
if (mut.getY() > minY) {
|
||||
mut.setY(mut.getY() + 1);
|
||||
BlocksHelper.setWithoutUpdate(world, mut, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean ignore(BlockState state, WorldGenLevel world, BlockPos pos) {
|
||||
if (state.is(CommonBlockTags.GEN_END_STONES) || state.is(BlockTags.NYLIUM)) {
|
||||
return true;
|
||||
}
|
||||
return !state.getMaterial().equals(Material.STONE) || BlocksHelper.isInvulnerable(state, world, pos);
|
||||
}
|
||||
|
||||
private static boolean isTerrainNear(WorldGenLevel world, BlockPos pos) {
|
||||
for (Direction dir : BlocksHelper.DIRECTIONS) {
|
||||
if (world.getBlockState(pos.relative(dir)).is(CommonBlockTags.GEN_END_STONES)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void cover(WorldGenLevel world, BoundingBox bounds, RandomSource random, BlockState defaultBlock) {
|
||||
MutableBlockPos mut = new MutableBlockPos();
|
||||
for (int x = bounds.minX(); x <= bounds.maxX(); x++) {
|
||||
mut.setX(x);
|
||||
for (int z = bounds.minZ(); z <= bounds.maxZ(); z++) {
|
||||
mut.setZ(z);
|
||||
BlockState top = BiomeAPI.findTopMaterial(world.getBiome(mut)).orElse(defaultBlock);
|
||||
if (top == null) continue;
|
||||
for (int y = bounds.maxY(); y >= bounds.minY(); y--) {
|
||||
mut.setY(y);
|
||||
BlockState state = world.getBlockState(mut);
|
||||
if (state.is(CommonBlockTags.TERRAIN) && !world.getBlockState(mut.above())
|
||||
.getMaterial()
|
||||
.isSolidBlocking()) {
|
||||
BlocksHelper.setWithoutUpdate(world, mut, top);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,12 +4,64 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class WeightedList<T> {
|
||||
|
||||
|
||||
private final List<Float> weights = new ArrayList<Float>();
|
||||
private final List<T> values = new ArrayList<T>();
|
||||
private float maxWeight;
|
||||
|
||||
public static <T> Codec<Pair<Float, T>> pairCodec(Codec<T> elementCodec, String fieldName) {
|
||||
return Pair.pairCodec(Codec.FLOAT, elementCodec, "weight", fieldName);
|
||||
}
|
||||
|
||||
public static <T> Codec<WeightedList<T>> listCodec(Codec<T> elementCodec, String fieldName, String elementName) {
|
||||
return RecordCodecBuilder.create(instance -> instance
|
||||
.group(
|
||||
pairCodec(elementCodec, elementName).listOf()
|
||||
.fieldOf(fieldName)
|
||||
.forGetter(WeightedList::pairs)
|
||||
)
|
||||
.apply(instance, WeightedList::new)
|
||||
);
|
||||
}
|
||||
|
||||
private List<Pair<Float, T>> pairs() {
|
||||
List<Pair<Float, T>> pairs = new ArrayList<>(weights.size());
|
||||
for (int i = 0; i < weights.size(); i++) {
|
||||
pairs.add(new Pair<>(weights.get(i), values.get(i)));
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
private WeightedList(List<Pair<Float, T>> pairs) {
|
||||
maxWeight = 0;
|
||||
for (var pair : pairs) {
|
||||
maxWeight += pair.first;
|
||||
weights.add(pair.first);
|
||||
values.add(pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
public WeightedList() {
|
||||
}
|
||||
|
||||
public <R> WeightedList<R> map(Function<T, R> map) {
|
||||
List<Pair<Float, R>> pairs = new ArrayList<>(weights.size());
|
||||
for (int i = 0; i < weights.size(); i++) {
|
||||
pairs.add(new Pair<>(weights.get(i), map.apply(values.get(i))));
|
||||
}
|
||||
return new WeightedList<>(pairs);
|
||||
}
|
||||
|
||||
public void addAll(WeightedList<T> other) {
|
||||
weights.addAll(other.weights);
|
||||
values.addAll(other.values);
|
||||
maxWeight += other.maxWeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds value with specified weight to the list
|
||||
*
|
||||
|
@ -37,6 +89,7 @@ public class WeightedList<T> {
|
|||
if (weight <= weights.get(i)) {
|
||||
return values.get(i);
|
||||
}
|
||||
weight -= weights.get(i);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,19 @@
|
|||
package org.betterx.worlds.together;
|
||||
|
||||
import org.betterx.bclib.util.Logger;
|
||||
import org.betterx.worlds.together.surfaceRules.SurfaceRuleRegistry;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
import org.betterx.worlds.together.util.Logger;
|
||||
import org.betterx.worlds.together.world.WorldConfig;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPresets;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
public class WorldsTogether {
|
||||
public class WorldsTogether implements ModInitializer {
|
||||
public static boolean SURPRESS_EXPERIMENTAL_DIALOG = false;
|
||||
public static boolean FORCE_SERVER_TO_BETTERX_PRESET = false;
|
||||
public static final String MOD_ID = "worlds_together";
|
||||
public static final Logger LOGGER = new Logger(MOD_ID);
|
||||
public static final boolean RUNS_TERRABLENDER = FabricLoader.getInstance()
|
||||
|
@ -22,7 +24,7 @@ public class WorldsTogether {
|
|||
return FabricLoader.getInstance().isDevelopmentEnvironment();
|
||||
}
|
||||
|
||||
public static void onInitialize() {
|
||||
public void onInitialize() {
|
||||
TagManager.ensureStaticallyLoaded();
|
||||
SurfaceRuleRegistry.ensureStaticallyLoaded();
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package org.betterx.worlds.together.biomesource;
|
||||
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public interface BiomeSourceFromRegistry {
|
||||
Registry<Biome> getBiomeRegistry();
|
||||
Set<Holder<Biome>> possibleBiomes();
|
||||
|
||||
default boolean sameRegistryButDifferentBiomes(BiomeSourceFromRegistry other) {
|
||||
if (other.getBiomeRegistry() == getBiomeRegistry()) {
|
||||
Set<Holder<Biome>> mySet = this.possibleBiomes();
|
||||
Set<Holder<Biome>> otherSet = other.possibleBiomes();
|
||||
if (otherSet.size() != mySet.size()) return true;
|
||||
for (Holder<Biome> b : mySet) {
|
||||
if (!otherSet.contains(b))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.betterx.worlds.together.biomesource;
|
||||
|
||||
public interface ReloadableBiomeSource {
|
||||
void reloadBiomes();
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.betterx.worlds.together.chunkgenerator;
|
||||
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceFromRegistry;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
|
@ -28,8 +29,14 @@ public interface EnforceableChunkGenerator<G extends ChunkGenerator> {
|
|||
if (one == two) return false;
|
||||
|
||||
if (one instanceof BiomeSourceWithConfig<?, ?> ba && two instanceof BiomeSourceWithConfig<?, ?> bb) {
|
||||
return !ba.getTogetherConfig().couldSetWithoutRepair(bb.getTogetherConfig());
|
||||
if (!ba.getTogetherConfig().couldSetWithoutRepair(bb.getTogetherConfig()))
|
||||
return true;
|
||||
}
|
||||
if (one instanceof BiomeSourceFromRegistry ba && two instanceof BiomeSourceFromRegistry bb) {
|
||||
if (ba.sameRegistryButDifferentBiomes(bb))
|
||||
return true;
|
||||
}
|
||||
|
||||
return !one.getClass().isAssignableFrom(two.getClass()) && !two.getClass().isAssignableFrom(one.getClass());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@ import net.minecraft.resources.ResourceKey;
|
|||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
|
||||
public interface RestorableBiomeSource<G extends ChunkGenerator> {
|
||||
public interface RestorableBiomeSource<B extends ChunkGenerator> {
|
||||
void restoreInitialBiomeSource(ResourceKey<LevelStem> dimensionKey);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ package org.betterx.worlds.together.client;
|
|||
|
||||
import org.betterx.worlds.together.worldPreset.client.WorldPresetsClient;
|
||||
|
||||
public class WorldsTogetherClient {
|
||||
public static void onInitializeClient() {
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
|
||||
public class WorldsTogetherClient implements ClientModInitializer {
|
||||
public void onInitializeClient() {
|
||||
WorldPresetsClient.setupClientside();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package org.betterx.worlds.together.entrypoints;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class EntrypointUtil {
|
||||
private static <T extends WorldsTogetherEntrypoint> List<T> getEntryPoints(boolean client, Class<T> select) {
|
||||
return FabricLoader.getInstance()
|
||||
.getEntrypoints(
|
||||
client ? "worlds_together_client" : "worlds_together",
|
||||
WorldsTogetherEntrypoint.class
|
||||
)
|
||||
.stream()
|
||||
.filter(o -> select.isAssignableFrom(o.getClass()))
|
||||
.map(e -> (T) e)
|
||||
.toList();
|
||||
}
|
||||
|
||||
public static <T extends WorldsTogetherEntrypoint> List<T> getCommon(Class<T> select) {
|
||||
return getEntryPoints(false, select);
|
||||
}
|
||||
|
||||
public static <T extends WorldsTogetherEntrypoint> List<T> getClient(Class<T> select) {
|
||||
return getEntryPoints(true, select);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package org.betterx.worlds.together.entrypoints;
|
||||
|
||||
public interface WorldPresetBootstrap extends WorldsTogetherEntrypoint {
|
||||
void bootstrapWorldPresets();
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package org.betterx.worlds.together.entrypoints;
|
||||
|
||||
public interface WorldsTogetherEntrypoint {
|
||||
}
|
|
@ -3,9 +3,12 @@ package org.betterx.worlds.together.levelgen;
|
|||
import org.betterx.bclib.util.MHelper;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.biomesource.BiomeSourceWithConfig;
|
||||
import org.betterx.worlds.together.biomesource.ReloadableBiomeSource;
|
||||
import org.betterx.worlds.together.chunkgenerator.EnforceableChunkGenerator;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithNoiseRelatedSettings;
|
||||
import org.betterx.worlds.together.world.BiomeSourceWithSeed;
|
||||
import org.betterx.worlds.together.world.WorldConfig;
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
import org.betterx.worlds.together.worldPreset.TogetherWorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPreset;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPresets;
|
||||
|
@ -20,6 +23,7 @@ import net.minecraft.world.level.biome.Biome;
|
|||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
import net.minecraft.world.level.levelgen.WorldGenSettings;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
|
@ -46,6 +50,11 @@ public class WorldGenUtil {
|
|||
if (stem.generator().getBiomeSource() instanceof BiomeSourceWithSeed bcl) {
|
||||
bcl.setSeed(seed);
|
||||
}
|
||||
|
||||
if (stem.generator().getBiomeSource() instanceof BiomeSourceWithNoiseRelatedSettings bcl
|
||||
&& stem.generator() instanceof NoiseBasedChunkGenerator noiseGenerator) {
|
||||
bcl.onLoadGeneratorSettings(noiseGenerator.generatorSettings().value());
|
||||
}
|
||||
}
|
||||
|
||||
return settings;
|
||||
|
@ -132,6 +141,7 @@ public class WorldGenUtil {
|
|||
) {
|
||||
var dimensions = TogetherWorldPreset.loadWorldDimensions();
|
||||
for (var entry : settings.dimensions().entrySet()) {
|
||||
boolean didRepair = false;
|
||||
ResourceKey<LevelStem> key = entry.getKey();
|
||||
LevelStem loadedStem = entry.getValue();
|
||||
|
||||
|
@ -147,6 +157,7 @@ public class WorldGenUtil {
|
|||
loadedChunkGenerator,
|
||||
settings
|
||||
);
|
||||
didRepair = true;
|
||||
} else if (loadedChunkGenerator.getBiomeSource() instanceof BiomeSourceWithConfig bs) {
|
||||
if (referenceGenerator.getBiomeSource() instanceof BiomeSourceWithConfig refbs) {
|
||||
if (!refbs.getTogetherConfig().sameConfig(bs.getTogetherConfig())) {
|
||||
|
@ -155,7 +166,26 @@ public class WorldGenUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!didRepair) {
|
||||
if (loadedStem.generator().getBiomeSource() instanceof ReloadableBiomeSource reload) {
|
||||
reload.reloadBiomes();
|
||||
}
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
public static ResourceLocation getBiomeID(Biome biome) {
|
||||
ResourceLocation id = null;
|
||||
RegistryAccess access = WorldBootstrap.getLastRegistryAccessOrElseBuiltin();
|
||||
|
||||
id = access.registryOrThrow(Registry.BIOME_REGISTRY).getKey(biome);
|
||||
|
||||
if (id == null) {
|
||||
WorldsTogether.LOGGER.error("Unable to get ID for " + biome + ".");
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public class CreateWorldScreenMixin {
|
|||
public WorldGenSettingsComponent worldGenSettingsComponent;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void bcl_init(
|
||||
private void wt_init(
|
||||
Screen screen,
|
||||
DataPackConfig dataPackConfig,
|
||||
WorldGenSettingsComponent worldGenSettingsComponent,
|
||||
|
@ -45,13 +45,13 @@ public class CreateWorldScreenMixin {
|
|||
|
||||
//Change the WorldPreset that is selected by default on the Create World Screen
|
||||
@ModifyArg(method = "openFresh", index = 1, at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screens/worldselection/WorldGenSettingsComponent;<init>(Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext;Ljava/util/Optional;Ljava/util/OptionalLong;)V"))
|
||||
private static Optional<ResourceKey<WorldPreset>> bcl_NewDefault(Optional<ResourceKey<WorldPreset>> preset) {
|
||||
private static Optional<ResourceKey<WorldPreset>> wt_NewDefault(Optional<ResourceKey<WorldPreset>> preset) {
|
||||
return Optional.of(WorldPresets.getDEFAULT());
|
||||
}
|
||||
|
||||
//Make sure the WorldGenSettings used to populate the create screen match the default WorldPreset
|
||||
@ModifyArg(method = "openFresh", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/WorldLoader;load(Lnet/minecraft/server/WorldLoader$InitConfig;Lnet/minecraft/server/WorldLoader$WorldDataSupplier;Lnet/minecraft/server/WorldLoader$ResultFactory;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
|
||||
private static WorldLoader.WorldDataSupplier<WorldGenSettings> bcl_NewDefaultSettings(WorldLoader.WorldDataSupplier<WorldGenSettings> worldDataSupplier) {
|
||||
private static WorldLoader.WorldDataSupplier<WorldGenSettings> wt_NewDefaultSettings(WorldLoader.WorldDataSupplier<WorldGenSettings> worldDataSupplier) {
|
||||
return (resourceManager, dataPackConfig) -> {
|
||||
Pair<WorldGenSettings, RegistryAccess.Frozen> res = worldDataSupplier.get(resourceManager, dataPackConfig);
|
||||
return WorldGenUtil.defaultWorldDataSupplier(res.getSecond());
|
||||
|
@ -60,7 +60,7 @@ public class CreateWorldScreenMixin {
|
|||
|
||||
//this is called when a new world is first created
|
||||
@Inject(method = "createNewWorldDirectory", at = @At("RETURN"))
|
||||
void bcl_createNewWorld(CallbackInfoReturnable<Optional<LevelStorageSource.LevelStorageAccess>> cir) {
|
||||
void wt_createNewWorld(CallbackInfoReturnable<Optional<LevelStorageSource.LevelStorageAccess>> cir) {
|
||||
WorldBootstrap.InGUI.registryReadyOnNewWorld(this.worldGenSettingsComponent);
|
||||
WorldBootstrap.InGUI.setupNewWorld(cir.getReturnValue(), this.worldGenSettingsComponent);
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public abstract class WorldOpenFlowsMixin {
|
|||
protected abstract void doLoadLevel(Screen screen, String levelID, boolean safeMode, boolean canAskForBackup);
|
||||
|
||||
@Inject(method = "loadLevel", cancellable = true, at = @At("HEAD"))
|
||||
private void bcl_callFixerOnLoad(Screen screen, String levelID, CallbackInfo ci) {
|
||||
private void wt_callFixerOnLoad(Screen screen, String levelID, CallbackInfo ci) {
|
||||
WorldBootstrap.InGUI.setupLoadedWorld(levelID, this.levelSource);
|
||||
|
||||
//if (DataFixerAPI.fixData(this.levelSource, levelID, true, (appliedFixes) -> {
|
||||
|
@ -53,7 +53,7 @@ public abstract class WorldOpenFlowsMixin {
|
|||
}
|
||||
|
||||
@Inject(method = "createFreshLevel", at = @At("HEAD"))
|
||||
public void bcl_createFreshLevel(
|
||||
public void wt_createFreshLevel(
|
||||
String levelID,
|
||||
LevelSettings levelSettings,
|
||||
RegistryAccess registryAccess,
|
||||
|
@ -64,7 +64,7 @@ public abstract class WorldOpenFlowsMixin {
|
|||
}
|
||||
|
||||
@Inject(method = "createLevelFromExistingSettings", at = @At("HEAD"))
|
||||
public void bcl_createLevelFromExistingSettings(
|
||||
public void wt_createLevelFromExistingSettings(
|
||||
LevelStorageSource.LevelStorageAccess levelStorageAccess,
|
||||
ReloadableServerResources reloadableServerResources,
|
||||
RegistryAccess.Frozen frozen,
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package org.betterx.worlds.together.mixin.common;
|
||||
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPresets;
|
||||
|
||||
import net.minecraft.server.dedicated.DedicatedServerProperties;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@Mixin(DedicatedServerProperties.class)
|
||||
public class DedicatedServerPropertiesMixin {
|
||||
//Make sure the default server properties use our Default World Preset by default (read from "level-type")
|
||||
@ModifyArg(method = "<init>", index = 3, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServerProperties$WorldGenProperties;<init>(Ljava/lang/String;Lcom/google/gson/JsonObject;ZLjava/lang/String;)V"))
|
||||
protected String wt_defaultPreset(String string) {
|
||||
if (WorldsTogether.FORCE_SERVER_TO_BETTERX_PRESET) {
|
||||
return WorldPresets.getDEFAULT().location().toString();
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
@ModifyArg(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/Settings;<init>(Ljava/util/Properties;)V"))
|
||||
private static Properties wt_defaultPreset(Properties property) {
|
||||
//init default value level preset in server.properties
|
||||
property.setProperty(
|
||||
"level-type",
|
||||
property.getProperty("level-type", WorldPresets.getDEFAULT().location().toString())
|
||||
);
|
||||
return property;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
|
||||
@Mixin(Main.class)
|
||||
@Mixin(value = Main.class, priority = 200)
|
||||
abstract public class MainMixin {
|
||||
@ModifyVariable(method = "main", ordinal = 0, at = @At(value = "INVOKE", shift = At.Shift.AFTER, target = "Lnet/minecraft/world/level/storage/LevelStorageSource$LevelStorageAccess;getSummary()Lnet/minecraft/world/level/storage/LevelSummary;"))
|
||||
private static LevelStorageSource.LevelStorageAccess bc_createAccess(LevelStorageSource.LevelStorageAccess levelStorageAccess) {
|
||||
|
|
|
@ -15,14 +15,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
|
||||
@Mixin(DedicatedServerProperties.WorldGenProperties.class)
|
||||
public class WorldGenPropertiesMixin {
|
||||
@Inject(method = "<init>", at = @At(value = "TAIL"))
|
||||
private static void bcl_create(String seed, JsonObject jsonObject, boolean bl, String string2, CallbackInfo ci) {
|
||||
return seed;
|
||||
}
|
||||
// @ModifyArg(method = "create", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/presets/WorldPreset;createWorldGenSettings(JZZ)Lnet/minecraft/world/level/levelgen/WorldGenSettings;"))
|
||||
// public long bcl_create(long seed) {
|
||||
// return seed;
|
||||
// }
|
||||
|
||||
//Make sure Servers use our Default World Preset
|
||||
@ModifyArg(method = "create", at = @At(value = "INVOKE", ordinal = 0, target = "Lnet/minecraft/core/Registry;getHolder(Lnet/minecraft/resources/ResourceKey;)Ljava/util/Optional;"))
|
||||
private ResourceKey<WorldPreset> bcl_foo(ResourceKey<WorldPreset> resourceKey) {
|
||||
private ResourceKey<WorldPreset> wt_returnDefault(ResourceKey<WorldPreset> resourceKey) {
|
||||
return WorldPresets.getDEFAULT();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.betterx.worlds.together.mixin.common;
|
||||
|
||||
import org.betterx.worlds.together.world.event.WorldBootstrap;
|
||||
|
||||
import net.minecraft.core.RegistryAccess;
|
||||
import net.minecraft.server.WorldLoader;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
|
||||
@Mixin(WorldLoader.class)
|
||||
public class WorldLoaderMixin {
|
||||
//this is the place a new Registry access gets first istantiated
|
||||
//either when a new Datapack was added to a world on the create-screen
|
||||
//or because we did start world loading
|
||||
@ModifyArg(method = "load", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/ReloadableServerResources;loadResources(Lnet/minecraft/server/packs/resources/ResourceManager;Lnet/minecraft/core/RegistryAccess$Frozen;Lnet/minecraft/commands/Commands$CommandSelection;ILjava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;"))
|
||||
private static RegistryAccess.Frozen wt_newRegistry(RegistryAccess.Frozen frozen) {
|
||||
WorldBootstrap.InGUI.registryReady(frozen);
|
||||
return frozen;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@ import org.jetbrains.annotations.ApiStatus;
|
|||
|
||||
public class SurfaceRuleRegistry {
|
||||
public static final ResourceKey<Registry<AssignedSurfaceRule>> SURFACE_RULES_REGISTRY =
|
||||
createRegistryKey(WorldsTogether.makeID("worldgen/surface_rules"));
|
||||
createRegistryKey(WorldsTogether.makeID("worldgen/betterx/surface_rules"));
|
||||
public static final Predicate<ResourceKey<LevelStem>> NON_MANAGED_DIMENSIONS = dim -> dim != LevelStem.NETHER && dim != LevelStem.END;
|
||||
public static final Predicate<ResourceKey<LevelStem>> ALL_DIMENSIONS = dim -> true;
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package org.betterx.worlds.together.tag.v3;
|
||||
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeAPI;
|
||||
import org.betterx.bclib.api.v2.tag.TagAPI;
|
||||
import org.betterx.worlds.together.levelgen.WorldGenUtil;
|
||||
import org.betterx.worlds.together.mixin.common.DiggerItemAccessor;
|
||||
import org.betterx.worlds.together.world.event.WorldEventsImpl;
|
||||
|
||||
import net.minecraft.core.DefaultedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -61,7 +61,7 @@ public class TagManager {
|
|||
"tags/worldgen/biome",
|
||||
(dir) -> new TagRegistry.Biomes(
|
||||
dir,
|
||||
b -> BiomeAPI.getBiomeID(b)
|
||||
b -> WorldGenUtil.getBiomeID(b)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class TagManager {
|
|||
String directory,
|
||||
Map<ResourceLocation, Tag.Builder> tagsMap
|
||||
) {
|
||||
tagsMap = TagAPI.apply(directory, tagsMap);
|
||||
WorldEventsImpl.BEFORE_ADDING_TAGS.emit(e -> e.apply(directory, tagsMap));
|
||||
|
||||
TagRegistry<?> type = TYPES.get(directory);
|
||||
if (type != null) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.betterx.worlds.together.tag.v3;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
|
||||
import net.minecraft.core.DefaultedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
|
@ -188,7 +188,7 @@ public class TagRegistry<T> {
|
|||
}
|
||||
|
||||
public void addUntyped(TagKey<T> tagID, ResourceLocation... elements) {
|
||||
if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
Set<Tag.Entry> set = getSetForTag(tagID);
|
||||
for (ResourceLocation id : elements) {
|
||||
if (id != null) {
|
||||
|
@ -204,7 +204,7 @@ public class TagRegistry<T> {
|
|||
}
|
||||
|
||||
public void addOtherTags(TagKey<T> tagID, TagKey<T>... tags) {
|
||||
if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
Set<Tag.Entry> set = getSetForTag(tagID);
|
||||
for (TagKey<T> tag : tags) {
|
||||
ResourceLocation id = tag.location();
|
||||
|
@ -221,7 +221,7 @@ public class TagRegistry<T> {
|
|||
* @param elements array of Elements to add into tag.
|
||||
*/
|
||||
protected void add(TagKey<T> tagID, T... elements) {
|
||||
if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
Set<Tag.Entry> set = getSetForTag(tagID);
|
||||
for (T element : elements) {
|
||||
ResourceLocation id = locationProvider.apply(element);
|
||||
|
@ -239,7 +239,7 @@ public class TagRegistry<T> {
|
|||
|
||||
@Deprecated(forRemoval = true)
|
||||
protected void add(ResourceLocation tagID, T... elements) {
|
||||
if (isFrozen) BCLib.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
if (isFrozen) WorldsTogether.LOGGER.warning("Adding Tag " + tagID + " after the API was frozen.");
|
||||
Set<Tag.Entry> set = getSetForTag(tagID);
|
||||
for (T element : elements) {
|
||||
ResourceLocation id = locationProvider.apply(element);
|
||||
|
@ -271,7 +271,7 @@ public class TagRegistry<T> {
|
|||
Tag.Builder builder,
|
||||
Set<Tag.Entry> ids
|
||||
) {
|
||||
ids.forEach(value -> builder.add(new Tag.BuilderEntry(value, BCLib.MOD_ID)));
|
||||
ids.forEach(value -> builder.add(new Tag.BuilderEntry(value, WorldsTogether.MOD_ID)));
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
62
src/main/java/org/betterx/worlds/together/util/Logger.java
Normal file
62
src/main/java/org/betterx/worlds/together/util/Logger.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package org.betterx.worlds.together.util;
|
||||
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
public final class Logger {
|
||||
private static final org.apache.logging.log4j.Logger LOGGER = LogManager.getLogger();
|
||||
private final String modPref;
|
||||
|
||||
public Logger(String modID) {
|
||||
this.modPref = "[" + modID + "] ";
|
||||
}
|
||||
|
||||
public void log(Level level, String message) {
|
||||
LOGGER.log(level, modPref + message);
|
||||
}
|
||||
|
||||
public void log(Level level, String message, Object... params) {
|
||||
LOGGER.log(level, modPref + message, params);
|
||||
}
|
||||
|
||||
public void debug(Object message) {
|
||||
this.log(Level.DEBUG, message.toString());
|
||||
}
|
||||
|
||||
public void debug(Object message, Object... params) {
|
||||
this.log(Level.DEBUG, message.toString(), params);
|
||||
}
|
||||
|
||||
public void catching(Throwable ex) {
|
||||
this.error(ex.getLocalizedMessage());
|
||||
LOGGER.catching(ex);
|
||||
}
|
||||
|
||||
public void info(String message) {
|
||||
this.log(Level.INFO, message);
|
||||
}
|
||||
|
||||
public void info(String message, Object... params) {
|
||||
this.log(Level.INFO, message, params);
|
||||
}
|
||||
|
||||
public void warning(String message, Object... params) {
|
||||
this.log(Level.WARN, message, params);
|
||||
}
|
||||
|
||||
public void warning(String message, Object obj, Exception ex) {
|
||||
LOGGER.warn(modPref + message, obj, ex);
|
||||
}
|
||||
|
||||
public void error(String message) {
|
||||
this.log(Level.ERROR, message);
|
||||
}
|
||||
|
||||
public void error(String message, Object obj, Exception ex) {
|
||||
LOGGER.error(modPref + message, obj, ex);
|
||||
}
|
||||
|
||||
public void error(String message, Exception ex) {
|
||||
LOGGER.error(modPref + message, ex);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package org.betterx.worlds.together.util;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
|
||||
import net.fabricmc.loader.api.*;
|
||||
|
@ -261,8 +260,6 @@ public class ModUtil {
|
|||
* @return The version of the locally installed Mod
|
||||
*/
|
||||
public static String getModVersion(String modID) {
|
||||
if (modID == WorldsTogether.MOD_ID) modID = BCLib.MOD_ID;
|
||||
|
||||
Optional<ModContainer> optional = FabricLoader.getInstance()
|
||||
.getModContainer(modID);
|
||||
if (optional.isPresent()) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package org.betterx.worlds.together.world;
|
||||
|
||||
import net.minecraft.world.level.levelgen.NoiseGeneratorSettings;
|
||||
|
||||
public interface BiomeSourceWithNoiseRelatedSettings {
|
||||
void onLoadGeneratorSettings(NoiseGeneratorSettings generator);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.betterx.worlds.together.world.event;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.TagLoader;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface BeforeAddingTags {
|
||||
void apply(
|
||||
String directory,
|
||||
Map<ResourceLocation, List<TagLoader.EntryWithSource>> tagsMap
|
||||
);
|
||||
}
|
|
@ -4,7 +4,7 @@ import java.util.LinkedList;
|
|||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class EventImpl<T> implements Event<T> {
|
||||
public class EventImpl<T> implements Event<T> {
|
||||
final List<T> handlers = new LinkedList<>();
|
||||
|
||||
public final boolean on(T handler) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.betterx.worlds.together.world.event;
|
||||
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.levelgen.WorldGenUtil;
|
||||
import org.betterx.worlds.together.mixin.common.RegistryOpsAccessor;
|
||||
|
@ -55,10 +54,6 @@ public class WorldBootstrap {
|
|||
|
||||
private static void initializeWorldConfig(File levelBaseDir, boolean newWorld) {
|
||||
WorldConfig.load(new File(levelBaseDir, "data"));
|
||||
|
||||
if (newWorld) {
|
||||
WorldConfig.saveFile(BCLib.MOD_ID);
|
||||
}
|
||||
}
|
||||
|
||||
private static void onRegistryReady(RegistryAccess a) {
|
||||
|
@ -114,7 +109,7 @@ public class WorldBootstrap {
|
|||
public static void setupWorld(LevelStorageSource.LevelStorageAccess levelStorageAccess) {
|
||||
File levelDat = levelStorageAccess.getLevelPath(LevelResource.LEVEL_DATA_FILE).toFile();
|
||||
if (!levelDat.exists()) {
|
||||
BCLib.LOGGER.info("Creating a new World, no fixes needed");
|
||||
WorldsTogether.LOGGER.info("Creating a new World, no fixes needed");
|
||||
final Map<ResourceKey<LevelStem>, ChunkGenerator> settings = Helpers.defaultServerDimensions();
|
||||
|
||||
Helpers.initializeWorldConfig(levelStorageAccess, true);
|
||||
|
@ -158,6 +153,10 @@ public class WorldBootstrap {
|
|||
}
|
||||
}
|
||||
|
||||
public static void registryReady(RegistryAccess access) {
|
||||
Helpers.onRegistryReady(access);
|
||||
}
|
||||
|
||||
public static void setupNewWorld(
|
||||
Optional<LevelStorageSource.LevelStorageAccess> levelStorageAccess,
|
||||
WorldGenSettingsComponent worldGenSettingsComponent
|
||||
|
@ -240,11 +239,11 @@ public class WorldBootstrap {
|
|||
false
|
||||
));
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Failed to initialize data in world", e);
|
||||
WorldsTogether.LOGGER.error("Failed to initialize data in world", e);
|
||||
}
|
||||
levelStorageAccess.close();
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Failed to acquire storage access", e);
|
||||
WorldsTogether.LOGGER.error("Failed to acquire storage access", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +258,7 @@ public class WorldBootstrap {
|
|||
result = WorldEventsImpl.PATCH_WORLD.applyPatches(levelStorageAccess, onResume);
|
||||
levelStorageAccess.close();
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Failed to initialize data in world", e);
|
||||
WorldsTogether.LOGGER.error("Failed to initialize data in world", e);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -286,7 +285,7 @@ public class WorldBootstrap {
|
|||
InGUI.setupNewWorldCommon(levelStorageAccess, worldPreset, worldGenSettings);
|
||||
levelStorageAccess.close();
|
||||
} catch (Exception e) {
|
||||
BCLib.LOGGER.error("Failed to initialize data in world", e);
|
||||
WorldsTogether.LOGGER.error("Failed to initialize data in world", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +313,7 @@ public class WorldBootstrap {
|
|||
return WorldGenUtil.repairBiomeSourceInAllDimensions(acc.bcl_getRegistryAccess(), worldGenSettings);
|
||||
//.repairSettingsOnLoad(LAST_REGISTRY_ACCESS, worldGenSettings);
|
||||
} else {
|
||||
BCLib.LOGGER.error("Unable to obtain registryAccess when enforcing generators.");
|
||||
WorldsTogether.LOGGER.error("Unable to obtain registryAccess when enforcing generators.");
|
||||
}
|
||||
return worldGenSettings;
|
||||
}
|
||||
|
|
|
@ -8,4 +8,6 @@ public class WorldEvents {
|
|||
public static final Event<OnFinalizeLevelStem> ON_FINALIZE_LEVEL_STEM = WorldEventsImpl.ON_FINALIZE_LEVEL_STEM;
|
||||
public static final Event<OnWorldPatch> PATCH_WORLD = WorldEventsImpl.PATCH_WORLD;
|
||||
public static final Event<OnAdaptWorldPresetSettings> ADAPT_WORLD_PRESET = WorldEventsImpl.ADAPT_WORLD_PRESET;
|
||||
|
||||
public static final Event<BeforeAddingTags> BEFORE_ADDING_TAGS = WorldEventsImpl.BEFORE_ADDING_TAGS;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package org.betterx.worlds.together.world.event;
|
||||
|
||||
class WorldEventsImpl {
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public class WorldEventsImpl {
|
||||
public static final EventImpl<OnWorldRegistryReady> WORLD_REGISTRY_READY = new EventImpl<>();
|
||||
public static final EventImpl<BeforeWorldLoad> BEFORE_WORLD_LOAD = new EventImpl<>();
|
||||
public static final EventImpl<BeforeServerWorldLoad> BEFORE_SERVER_WORLD_LOAD = new EventImpl<>();
|
||||
|
@ -10,4 +13,6 @@ class WorldEventsImpl {
|
|||
|
||||
public static final PatchWorldEvent PATCH_WORLD = new PatchWorldEvent();
|
||||
public static final AdaptWorldPresetSettingEvent ADAPT_WORLD_PRESET = new AdaptWorldPresetSettingEvent();
|
||||
|
||||
public static final EventImpl<BeforeAddingTags> BEFORE_ADDING_TAGS = new EventImpl<>();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package org.betterx.worlds.together.worldPreset;
|
||||
|
||||
import org.betterx.bclib.registry.PresetsRegistry;
|
||||
import org.betterx.worlds.together.WorldsTogether;
|
||||
import org.betterx.worlds.together.entrypoints.EntrypointUtil;
|
||||
import org.betterx.worlds.together.entrypoints.WorldPresetBootstrap;
|
||||
import org.betterx.worlds.together.levelgen.WorldGenUtil;
|
||||
import org.betterx.worlds.together.tag.v3.TagManager;
|
||||
import org.betterx.worlds.together.tag.v3.TagRegistry;
|
||||
|
@ -109,7 +110,8 @@ public class WorldPresets {
|
|||
WorldGenUtil.Context netherContext,
|
||||
WorldGenUtil.Context endContext
|
||||
) {
|
||||
PresetsRegistry.onLoad();
|
||||
EntrypointUtil.getCommon(WorldPresetBootstrap.class)
|
||||
.forEach(e -> e.bootstrapWorldPresets());
|
||||
|
||||
for (Map.Entry<ResourceKey<WorldPreset>, PresetBuilder> e : BUILDERS.entrySet()) {
|
||||
TogetherWorldPreset preset = e.getValue().create(overworldStem, netherContext, endContext);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
package org.betterx.worlds.together.worldPreset.client;
|
||||
|
||||
import org.betterx.bclib.registry.PresetsRegistryClient;
|
||||
import org.betterx.worlds.together.worldPreset.WorldPreset;
|
||||
|
||||
import org.betterx.worlds.together.worldPreset.WorldPreset;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
@ -19,6 +18,5 @@ public class WorldPresetsClient {
|
|||
}
|
||||
|
||||
public static void setupClientside() {
|
||||
PresetsRegistryClient.onLoad();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyXZCondition
|
|||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$LazyCondition
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource
|
||||
extendable class net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator
|
||||
accessible class net/minecraft/data/BuiltinRegistries$RegistryBootstrap
|
||||
accessible class net/minecraft/core/Registry$RegistryBootstrap
|
||||
accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource
|
||||
accessible class net/minecraft/core/Registry$RegistryBootstrap
|
||||
accessible class net/minecraft/tags/Tag$ElementEntry
|
||||
|
@ -27,3 +29,5 @@ accessible field net/minecraft/client/gui/screens/worldselection/WorldPreset SIN
|
|||
accessible field net/minecraft/client/gui/screens/worldselection/WorldPreset PRESETS Ljava/util/List;
|
||||
accessible field net/minecraft/client/gui/screens/worldselection/WorldPreset EDITORS Ljava/util/Map;
|
||||
|
||||
|
||||
accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry;
|
|
@ -10,12 +10,12 @@
|
|||
"BiomeMixin",
|
||||
"BiomeSourceMixin",
|
||||
"BoneMealItemMixin",
|
||||
"BuiltinRegistriesMixin",
|
||||
"ChunkGeneratorAccessor",
|
||||
"ChunkGeneratorMixin",
|
||||
"ChunkGeneratorsMixin",
|
||||
"ComposterBlockAccessor",
|
||||
"CraftingMenuMixin",
|
||||
"DedicatedServerPropertiesMixin",
|
||||
"DiggerItemMixin",
|
||||
"EnchantingTableBlockMixin",
|
||||
"ItemStackMixin",
|
||||
|
@ -29,11 +29,12 @@
|
|||
"PotionBrewingAccessor",
|
||||
"RecipeManagerAccessor",
|
||||
"RecipeManagerMixin",
|
||||
"RegistryAccessMixin",
|
||||
"ServerLevelMixin",
|
||||
"ShovelItemAccessor",
|
||||
"StructuresAccessor",
|
||||
"SurfaceRulesContextAccessor",
|
||||
"TheEndBiomeDataMixin",
|
||||
"TheEndBiomesMixin",
|
||||
"WorldGenRegionMixin",
|
||||
"elytra.LivingEntityMixin",
|
||||
"shears.BeehiveBlockMixin",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "bclib",
|
||||
"version": "2.0.8",
|
||||
"version": "2.0.11",
|
||||
"name": "BCLib",
|
||||
"description": "A library for BetterX team mods",
|
||||
"authors": [
|
||||
|
@ -29,6 +29,9 @@
|
|||
],
|
||||
"modmenu": [
|
||||
"org.betterx.bclib.integration.modmenu.ModMenuEntryPoint"
|
||||
],
|
||||
"worlds_together": [
|
||||
"org.betterx.bclib.registry.PresetsRegistry"
|
||||
]
|
||||
},
|
||||
"accessWidener": "bclib.accesswidener",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"BuiltinRegistriesMixin",
|
||||
"DedicatedServerPropertiesMixin",
|
||||
"DiggerItemAccessor",
|
||||
"MainMixin",
|
||||
"MinecraftServerMixin",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"RegistryOpsAccessor",
|
||||
"TagLoaderMixin",
|
||||
"WorldGenPropertiesMixin",
|
||||
"WorldLoaderMixin",
|
||||
"WorldPresetAccessor",
|
||||
"WorldPresetMixin",
|
||||
"WorldPresetsBootstrapMixin"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue