[Change] BCLBiome Data is managed in a Datapack-Aware registry now
This commit is contained in:
parent
94c08e79b2
commit
32e7ffec69
29 changed files with 910 additions and 145 deletions
|
@ -8,7 +8,7 @@ minecraft_version=1.19
|
|||
loader_version=0.14.8
|
||||
fabric_version=0.57.0+1.19
|
||||
# Mod Properties
|
||||
mod_version=2.0.10
|
||||
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;
|
||||
|
@ -42,6 +43,7 @@ public class BCLib implements ModInitializer {
|
|||
public void onInitialize() {
|
||||
LevelGenEvents.register();
|
||||
BlockPredicates.ensureStaticInitialization();
|
||||
BCLBiomeRegistry.ensureStaticallyLoaded();
|
||||
BaseRegistry.register();
|
||||
GeneratorOptions.init();
|
||||
BaseBlockEntities.register();
|
||||
|
|
|
@ -6,6 +6,7 @@ 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;
|
||||
|
@ -110,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,10 +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.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;
|
||||
|
@ -32,7 +34,7 @@ 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
|
||||
|
@ -61,7 +63,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
private BiomeMap mapCenter;
|
||||
private BiomeMap mapBarrens;
|
||||
|
||||
private final BiomePicker endLandBiomePicker;
|
||||
private BiomePicker endLandBiomePicker;
|
||||
private BiomePicker endVoidBiomePicker;
|
||||
private BiomePicker endCenterBiomePicker;
|
||||
private BiomePicker endBarrensBiomePicker;
|
||||
|
@ -94,13 +96,25 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
) {
|
||||
super(biomeRegistry, list, seed);
|
||||
this.config = config;
|
||||
rebuildBiomePickers();
|
||||
|
||||
this.endLandFunction = GeneratorOptions.getEndLandFunction();
|
||||
this.pos = new Point();
|
||||
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private void rebuildBiomePickers() {
|
||||
var includeMap = Configs.BIOMES_CONFIG.getBiomeIncludeMap();
|
||||
var excludeList = Configs.BIOMES_CONFIG.getExcludeMatching(BiomeAPI.BiomeType.END);
|
||||
|
||||
endLandBiomePicker = new BiomePicker(biomeRegistry);
|
||||
endVoidBiomePicker = new BiomePicker(biomeRegistry);
|
||||
endCenterBiomePicker = new BiomePicker(biomeRegistry);
|
||||
endBarrensBiomePicker = new BiomePicker(biomeRegistry);
|
||||
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);
|
||||
|
@ -126,7 +140,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
}
|
||||
|
||||
|
||||
if (bclBiome != null || bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome != null || bclBiome != BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() == null) {
|
||||
//ignore small islands when void biomes are disabled
|
||||
if (!config.withVoidBiomes) {
|
||||
|
@ -168,7 +182,6 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
endLandBiomePicker.rebuild();
|
||||
|
@ -194,20 +207,15 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
endCenterBiomePicker = endLandBiomePicker;
|
||||
}
|
||||
}
|
||||
|
||||
this.endLandFunction = GeneratorOptions.getEndLandFunction();
|
||||
this.pos = new Point();
|
||||
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -235,7 +243,7 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
|
||||
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.canGenerateInEnd(biome.unwrapKey().orElse(null));
|
||||
|
@ -363,4 +371,10 @@ public class BCLibEndBiomeSource extends BCLBiomeSource implements BiomeSourceWi
|
|||
this.config = newConfig;
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadBiomes() {
|
||||
rebuildBiomePickers();
|
||||
this.initMap(currentSeed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,13 @@ import org.betterx.bclib.BCLib;
|
|||
import org.betterx.bclib.api.v2.generator.config.BCLNetherBiomeSourceConfig;
|
||||
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.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;
|
||||
|
@ -26,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(
|
||||
|
@ -49,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) {
|
||||
|
@ -78,6 +80,13 @@ 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 -> {
|
||||
|
@ -87,12 +96,13 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
return;
|
||||
}
|
||||
if (!BiomeAPI.hasBiome(biomeID)) {
|
||||
|
||||
BCLBiome bclBiome = new BCLBiome(biomeID, biome.value());
|
||||
biomePicker.addBiome(bclBiome);
|
||||
} else {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biomeID);
|
||||
|
||||
if (bclBiome != BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome != BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
if (bclBiome.getParentBiome() == null) {
|
||||
biomePicker.addBiome(bclBiome);
|
||||
}
|
||||
|
@ -101,9 +111,6 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
});
|
||||
|
||||
biomePicker.rebuild();
|
||||
if (initMaps) {
|
||||
initMap(seed);
|
||||
}
|
||||
}
|
||||
|
||||
protected BCLBiomeSource cloneForDatapack(Set<Holder<Biome>> datapackBiomes) {
|
||||
|
@ -213,4 +220,10 @@ public class BCLibNetherBiomeSource extends BCLBiomeSource implements BiomeSourc
|
|||
this.config = newConfig;
|
||||
initMap(currentSeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadBiomes() {
|
||||
rebuildBiomePicker();
|
||||
initMap(currentSeed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class BiomePicker {
|
|||
.map(h -> h.unwrapKey())
|
||||
.filter(o -> o.isPresent())
|
||||
.map(o -> o.get().location().toString()).toList() : null;
|
||||
this.fallbackBiome = create(BiomeAPI.EMPTY_BIOME);
|
||||
this.fallbackBiome = create(BCLBiomeRegistry.EMPTY_BIOME);
|
||||
}
|
||||
|
||||
private boolean isAllowed(BCLBiome b) {
|
||||
|
@ -83,7 +83,7 @@ public class BiomePicker {
|
|||
|
||||
//no Biome, make sure we add at least one, otherwise bad things will happen
|
||||
if (list.isEmpty()) {
|
||||
list.add(create(BiomeAPI.EMPTY_BIOME), 1);
|
||||
list.add(create(BCLBiomeRegistry.EMPTY_BIOME), 1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -161,4 +161,13 @@ public class BiomePicker {
|
|||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BiomePicker{" +
|
||||
"biomes=" + biomes.size() + " (" + all.size() + ")" +
|
||||
", biomeRegistry=" + biomeRegistry +
|
||||
", type=" + super.toString() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,39 +2,179 @@ package org.betterx.bclib.api.v2.levelgen.biomes;
|
|||
|
||||
import org.betterx.bclib.util.WeightedList;
|
||||
|
||||
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> 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 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.
|
||||
*
|
||||
|
@ -81,6 +221,7 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
* @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);
|
||||
}
|
||||
|
@ -124,6 +265,25 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
BiomeAPI.BiomeType getIntendedType() {
|
||||
return this.intendedType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current biome edge.
|
||||
*
|
||||
|
@ -250,6 +410,10 @@ public class BCLBiome extends BCLBiomeSettings {
|
|||
return biomeKey;
|
||||
}
|
||||
|
||||
public ResourceKey<BCLBiome> getBCLBiomeKey() {
|
||||
return ResourceKey.create(BCLBiomeRegistry.BCL_BIOMES_REGISTRY, biomeID);
|
||||
}
|
||||
|
||||
/**
|
||||
* For internal use from BiomeAPI only
|
||||
*/
|
||||
|
@ -291,6 +455,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;
|
||||
|
@ -302,6 +467,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;
|
||||
|
|
|
@ -54,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,
|
||||
|
@ -709,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);
|
||||
|
@ -850,6 +909,8 @@ public class BCLBiomeBuilder {
|
|||
//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));
|
||||
|
|
|
@ -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;
|
||||
|
@ -38,53 +40,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 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 END_BARRENS = new BiomeType("END_BARRENS", END);
|
||||
public static final BiomeType BCL_END_LAND = new BiomeType("BCL_END_LAND", END_LAND);
|
||||
public static final BiomeType BCL_END_VOID = new BiomeType("BCL_END_VOID", END_VOID);
|
||||
public static final BiomeType BCL_END_CENTER = new BiomeType("BCL_END_CENTER", END_CENTER);
|
||||
public static final BiomeType BCL_END_BARRENS = new BiomeType("BCL_END_BARRENS", END_BARRENS);
|
||||
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 name;
|
||||
|
||||
@FunctionalInterface
|
||||
interface ExtraRegisterTaks {
|
||||
void register(@NotNull BCLBiome biome, @Nullable BCLBiome parent);
|
||||
}
|
||||
|
||||
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.name = name;
|
||||
this.extraRegisterTask = extraRegisterTask;
|
||||
KNOWN_TYPES.put(name, this);
|
||||
}
|
||||
|
||||
public boolean is(BiomeType d) {
|
||||
|
@ -108,10 +199,10 @@ public class BiomeAPI {
|
|||
/**
|
||||
* 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());
|
||||
|
||||
private static final Map<ResourceLocation, BCLBiome> ID_MAP = Maps.newHashMap();
|
||||
public static final BCLBiome EMPTY_BIOME = BCLBiomeRegistry.EMPTY_BIOME;
|
||||
|
||||
public static final BCLBiome NETHER_WASTES_BIOME = InternalBiomeAPI.wrapNativeBiome(
|
||||
Biomes.NETHER_WASTES,
|
||||
|
@ -166,6 +257,16 @@ public class BiomeAPI {
|
|||
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.
|
||||
*
|
||||
|
@ -173,6 +274,7 @@ public class BiomeAPI {
|
|||
* @param dim The Dimension fo rthis Biome
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public static BCLBiome registerBiome(BCLBiome bclbiome, BiomeType dim) {
|
||||
return registerBiome(bclbiome, dim, BuiltinRegistries.BIOME);
|
||||
}
|
||||
|
@ -184,15 +286,27 @@ public class BiomeAPI {
|
|||
* @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);
|
||||
}
|
||||
|
||||
ID_MAP.put(bclbiome.getID(), bclbiome);
|
||||
BiomeType.BIOME_TYPE_MAP.put(bclbiome.getID(), dim);
|
||||
BCLBiomeRegistry.register(bclbiome);
|
||||
}
|
||||
|
||||
if (dim != null && dim.is(BiomeType.NETHER)) {
|
||||
TagManager.BIOMES.add(BiomeTags.IS_NETHER, bclbiome.getBiomeKey());
|
||||
|
@ -211,7 +325,7 @@ public class BiomeAPI {
|
|||
return registerSubBiome(
|
||||
parent,
|
||||
subBiome,
|
||||
BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE)
|
||||
parent.getIntendedType()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -220,7 +334,7 @@ public class BiomeAPI {
|
|||
parent,
|
||||
subBiome,
|
||||
genChance,
|
||||
BiomeType.BIOME_TYPE_MAP.getOrDefault(parent.getID(), BiomeType.NONE)
|
||||
parent.getIntendedType()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -248,14 +362,14 @@ public class BiomeAPI {
|
|||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (biome.allowFabricRegistration()) {
|
||||
if (biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = biome.getParentBiome().getBiomeKey();
|
||||
TheEndBiomes.addMidlandsBiome(parentKey, key, weight);
|
||||
} else {
|
||||
TheEndBiomes.addHighlandsBiome(key, weight);
|
||||
}
|
||||
|
||||
if (biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = biome.getParentBiome().getBiomeKey();
|
||||
TheEndBiomes.addMidlandsBiome(parentKey, key, weight);
|
||||
} else {
|
||||
TheEndBiomes.addHighlandsBiome(key, weight);
|
||||
}
|
||||
|
||||
return biome;
|
||||
}
|
||||
|
||||
|
@ -272,7 +386,7 @@ public class BiomeAPI {
|
|||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (biome.allowFabricRegistration()) {
|
||||
if (!biome.isEdgeBiome()) {
|
||||
TheEndBiomes.addSmallIslandsBiome(key, weight);
|
||||
}
|
||||
return biome;
|
||||
|
@ -291,7 +405,7 @@ public class BiomeAPI {
|
|||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (biome.allowFabricRegistration()) {
|
||||
if (!biome.isEdgeBiome()) {
|
||||
TheEndBiomes.addMainIslandBiome(key, weight);
|
||||
}
|
||||
return biome;
|
||||
|
@ -310,7 +424,7 @@ public class BiomeAPI {
|
|||
|
||||
float weight = biome.getGenChance();
|
||||
ResourceKey<Biome> key = biome.getBiomeKey();
|
||||
if (biome.allowFabricRegistration()) {
|
||||
if (!biome.isEdgeBiome()) {
|
||||
ResourceKey<Biome> parentKey = highlandBiome.getBiomeKey();
|
||||
TheEndBiomes.addBarrensBiome(parentKey, key, weight);
|
||||
}
|
||||
|
@ -318,17 +432,20 @@ public class BiomeAPI {
|
|||
}
|
||||
|
||||
|
||||
public static BCLBiome registerEndBiome(Holder<Biome> biome) {
|
||||
BCLBiome bclBiome = new BCLBiome(biome.value(), null);
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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);
|
||||
ResourceKey<Biome> key = bclBiome.getBiomeKey();
|
||||
if (!bclBiome.isEdgeBiome()) {
|
||||
bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
|
||||
}
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
|
@ -342,9 +459,13 @@ public class BiomeAPI {
|
|||
@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()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -353,15 +474,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;
|
||||
|
@ -401,7 +522,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;
|
||||
|
@ -414,11 +535,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) {
|
||||
|
@ -462,7 +582,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -492,7 +613,7 @@ 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;
|
||||
}
|
||||
|
||||
public static Holder<Biome> getFromRegistry(ResourceLocation biomeID) {
|
||||
|
@ -537,12 +658,9 @@ public class BiomeAPI {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
@ -883,22 +1001,6 @@ public class BiomeAPI {
|
|||
return features.get(index).stream().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
* After that biome will be added to BCLib Nether Biome Generator and into Fabric Biome API.
|
||||
*
|
||||
* @param bclBiome {@link BCLBiome}
|
||||
* @return {@link BCLBiome}
|
||||
*/
|
||||
public static BCLBiome registerNetherBiome(BCLBiome bclBiome) {
|
||||
registerBiome(bclBiome, BiomeType.BCL_NETHER);
|
||||
|
||||
ResourceKey<Biome> key = bclBiome.getBiomeKey();
|
||||
if (bclBiome.allowFabricRegistration()) {
|
||||
bclBiome.forEachClimateParameter(p -> NetherBiomes.addNetherBiome(key, p));
|
||||
}
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register {@link BCLBiome} instance and its {@link Biome} if necessary.
|
||||
|
@ -962,4 +1064,22 @@ public class BiomeAPI {
|
|||
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();
|
||||
}
|
|
@ -165,16 +165,10 @@ 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.getFromRegistry(id);
|
||||
|
@ -326,11 +320,12 @@ public class InternalBiomeAPI {
|
|||
BiomeAPI.BiomeType type
|
||||
) {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biomeKey.location());
|
||||
if (bclBiome == BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
bclBiome = new BCLBiome(biomeKey, setings);
|
||||
bclBiome._setIntendedType(type);
|
||||
}
|
||||
|
||||
BiomeAPI.registerBiome(bclBiome, type);
|
||||
BiomeAPI.registerBiome(bclBiome);
|
||||
return bclBiome;
|
||||
}
|
||||
|
||||
|
@ -345,7 +340,7 @@ public class InternalBiomeAPI {
|
|||
@Deprecated(forRemoval = true)
|
||||
static BCLBiome wrapNativeBiome(Biome biome, float genChance, BiomeAPI.BiomeType type) {
|
||||
BCLBiome bclBiome = BiomeAPI.getBiome(biome);
|
||||
if (bclBiome == BiomeAPI.EMPTY_BIOME) {
|
||||
if (bclBiome == BCLBiomeRegistry.EMPTY_BIOME) {
|
||||
bclBiome = new BCLBiome(
|
||||
biome,
|
||||
genChance < 0 ? null : VanillaBiomeSettings.createVanilla().setGenChance(genChance).build()
|
||||
|
@ -363,7 +358,7 @@ 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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package org.betterx.bclib.commands;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BCLBiome;
|
||||
import org.betterx.bclib.api.v2.levelgen.biomes.BiomeData;
|
||||
import org.betterx.bclib.blocks.BaseStairsBlock;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.serialization.Codec;
|
||||
|
@ -27,8 +28,11 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.RuleTestType;
|
|||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorType;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import org.betterx.bclib.BCLib;
|
||||
import org.betterx.bclib.blocks.BaseStairsBlock;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.awt.Taskbar.Feature;
|
||||
import java.io.File;
|
||||
|
@ -113,13 +117,15 @@ public class DumpDatapack {
|
|||
while (obj instanceof Holder<?>) {
|
||||
obj = ((Holder<?>) obj).value();
|
||||
}
|
||||
|
||||
|
||||
if (obj instanceof BiomeSource || obj instanceof Feature) {
|
||||
System.out.print("");
|
||||
}
|
||||
|
||||
|
||||
if (obj instanceof Structure s) {
|
||||
codec[0] = s.type().codec();
|
||||
} else if (obj instanceof BCLBiome s) {
|
||||
codec[0] = BiomeData.CODEC;
|
||||
} else if (obj instanceof StructureProcessorList s) {
|
||||
codec[0] = StructureProcessorType.LIST_OBJECT_CODEC;
|
||||
} else if (obj instanceof GameEvent) {
|
||||
|
@ -134,9 +140,9 @@ public class DumpDatapack {
|
|||
codec[0] = registry.value().byNameCodec();
|
||||
} else if (obj instanceof PosRuleTestType<?>) {
|
||||
codec[0] = registry.value().byNameCodec();
|
||||
}else if (obj instanceof WorldGenSettings) {
|
||||
} else if (obj instanceof WorldGenSettings) {
|
||||
codec[0] = registry.value().byNameCodec();
|
||||
}else if (obj instanceof LevelStem) {
|
||||
} else if (obj instanceof LevelStem) {
|
||||
codec[0] = registry.value().byNameCodec();
|
||||
}
|
||||
|
||||
|
@ -225,8 +231,8 @@ public class DumpDatapack {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (codec[0]==null){
|
||||
|
||||
if (codec[0] == null) {
|
||||
codec[0] = registry.value().byNameCodec();
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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,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;
|
||||
|
||||
|
|
|
@ -1,17 +1,71 @@
|
|||
package org.betterx.bclib.util;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import net.minecraft.util.RandomSource;
|
||||
|
||||
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
|
||||
*
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package org.betterx.worlds.together.biomesource;
|
||||
|
||||
public interface ReloadableBiomeSource {
|
||||
void reloadBiomes();
|
||||
}
|
|
@ -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,6 +2,7 @@ package org.betterx.worlds.together.levelgen;
|
|||
|
||||
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;
|
||||
|
@ -141,6 +142,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();
|
||||
|
||||
|
@ -156,6 +158,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())) {
|
||||
|
@ -164,6 +167,12 @@ public class WorldGenUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!didRepair) {
|
||||
if (loadedStem.generator().getBiomeSource() instanceof ReloadableBiomeSource reload) {
|
||||
reload.reloadBiomes();
|
||||
}
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -154,6 +154,10 @@ public class WorldBootstrap {
|
|||
}
|
||||
}
|
||||
|
||||
public static void registryReady(RegistryAccess access) {
|
||||
Helpers.onRegistryReady(access);
|
||||
}
|
||||
|
||||
public static void setupNewWorld(
|
||||
Optional<LevelStorageSource.LevelStorageAccess> levelStorageAccess,
|
||||
WorldGenSettingsComponent worldGenSettingsComponent
|
||||
|
|
|
@ -11,10 +11,12 @@ accessible class net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSou
|
|||
accessible class net/minecraft/world/level/levelgen/presets/WorldPresets$Bootstrap
|
||||
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
|
||||
|
||||
#Methods
|
||||
accessible method net/minecraft/client/gui/screens/worldselection/WorldGenSettingsComponent updateSettings (Lnet/minecraft/client/gui/screens/worldselection/WorldCreationContext$Updater;)V
|
||||
accessible method net/minecraft/world/level/storage/loot/LootPool <init> ([Lnet/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer;[Lnet/minecraft/world/level/storage/loot/predicates/LootItemCondition;[Lnet/minecraft/world/level/storage/loot/functions/LootItemFunction;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;)V
|
||||
accessible method net/minecraft/world/entity/ai/village/poi/PoiTypes register (Lnet/minecraft/core/Registry;Lnet/minecraft/resources/ResourceKey;Ljava/util/Set;II)Lnet/minecraft/world/entity/ai/village/poi/PoiType;
|
||||
accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource <init> (Ljava/util/List;)V
|
||||
accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource <init> (Ljava/util/List;)V
|
||||
accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry;
|
|
@ -10,6 +10,7 @@
|
|||
"BiomeMixin",
|
||||
"BiomeSourceMixin",
|
||||
"BoneMealItemMixin",
|
||||
"BuiltinRegistriesMixin",
|
||||
"ChunkGeneratorAccessor",
|
||||
"ChunkGeneratorMixin",
|
||||
"ChunkGeneratorsMixin",
|
||||
|
@ -28,6 +29,7 @@
|
|||
"PotionBrewingAccessor",
|
||||
"RecipeManagerAccessor",
|
||||
"RecipeManagerMixin",
|
||||
"RegistryAccessMixin",
|
||||
"ServerLevelMixin",
|
||||
"ShovelItemAccessor",
|
||||
"StructuresAccessor",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "bclib",
|
||||
"version": "2.0.10",
|
||||
"version": "2.0.11",
|
||||
"name": "BCLib",
|
||||
"description": "A library for BetterX team mods",
|
||||
"authors": [
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"RegistryOpsAccessor",
|
||||
"TagLoaderMixin",
|
||||
"WorldGenPropertiesMixin",
|
||||
"WorldLoaderMixin",
|
||||
"WorldPresetAccessor",
|
||||
"WorldPresetMixin",
|
||||
"WorldPresetsBootstrapMixin"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue