Sample code to write Biome-Tags in Datagen

This commit is contained in:
Frank 2022-12-03 01:41:44 +01:00
parent 90be8a3160
commit d279b6dfd0
7 changed files with 256 additions and 40 deletions

View file

@ -2,10 +2,7 @@ package org.betterx.datagen.bclib;
import org.betterx.bclib.BCLib;
import org.betterx.datagen.bclib.preset.WorldPresetDataProvider;
import org.betterx.datagen.bclib.tests.TestBiomes;
import org.betterx.datagen.bclib.tests.TestConfiguredFeatures;
import org.betterx.datagen.bclib.tests.TestPlacedFeatures;
import org.betterx.datagen.bclib.tests.TestWorldgenProvider;
import org.betterx.datagen.bclib.tests.*;
import org.betterx.datagen.bclib.worldgen.BCLibRegistriesDataProvider;
import org.betterx.datagen.bclib.worldgen.NoiseTypesDataProvider;
import org.betterx.datagen.bclib.worldgen.VanillaBCLBiomesDataProvider;
@ -29,6 +26,7 @@ public class BCLibDatagen implements DataGeneratorEntrypoint {
if (ADD_TESTS) {
pack.addProvider(TestWorldgenProvider::new);
pack.addProvider(TestBiomes::new);
}
pack.addProvider(WorldgenRegistriesDataProvider::new);
@ -42,9 +40,13 @@ public class BCLibDatagen implements DataGeneratorEntrypoint {
if (ADD_TESTS) {
registryBuilder.add(Registries.CONFIGURED_FEATURE, TestConfiguredFeatures::bootstrap);
registryBuilder.add(Registries.PLACED_FEATURE, TestPlacedFeatures::bootstrap);
//registryBuilder.add(Registries.STRUCTURE_PIECE, TestStructure::bootstrapPiece);
//registryBuilder.add(Registries.STRUCTURE_TYPE, TestStructure::bootstrapType);
registryBuilder.add(Registries.STRUCTURE, TestStructure::bootstrap);
}
registryBuilder.add(Registries.BIOME, TestBiomes::bootstrap);
registryBuilder.add(Registries.NOISE_SETTINGS, NoiseTypesDataProvider::bootstrap);
registryBuilder.add(Registries.WORLD_PRESET, WorldPresetDataProvider::bootstrap);
}
}

View file

@ -5,12 +5,20 @@ 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.BCLBiomeContainer;
import org.betterx.datagen.bclib.BCLibDatagen;
import org.betterx.worlds.together.tag.v3.TagManager;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.block.Blocks;
public class TestBiomes {
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import java.util.concurrent.CompletableFuture;
public class TestBiomes extends FabricTagProvider<Biome> {
static BCLBiomeContainer<BCLBiome> THE_YELLOW = BCLBiomeBuilder
.start(BCLib.makeID("the_yellow"))
.precipitation(Biome.Precipitation.NONE)
@ -26,13 +34,7 @@ public class TestBiomes {
.endLandBiome()
.build();
public static void bootstrap(BootstapContext<Biome> bootstrapContext) {
BCLib.LOGGER.info("Bootstrap Biomes");
if (BCLibDatagen.ADD_TESTS && BCLib.isDevEnvironment()) {
BCLBiomeContainer<BCLBiome> theYellow = THE_YELLOW
.register(bootstrapContext);
BCLBiome theBlue = BCLBiomeBuilder
static BCLBiomeContainer<BCLBiome> THE_BLUE = BCLBiomeBuilder
.start(BCLib.makeID("the_blue"))
.precipitation(Biome.Precipitation.NONE)
.temperature(1.0f)
@ -43,9 +45,30 @@ public class TestBiomes {
.skyColor(0x0000AA)
.addNetherClimateParamater(-1, 1)
.surface(Blocks.LIGHT_BLUE_CONCRETE)
.structure(TestStructure.TEST_STRUCTURE_TAG)
.endLandBiome()
.build()
.register(bootstrapContext).biome();
.build();
/**
* Constructs a new {@link FabricTagProvider} with the default computed path.
*
* <p>Common implementations of this class are provided.
*
* @param output the {@link FabricDataOutput} instance
* @param registriesFuture the backing registry for the tag type
*/
public TestBiomes(
FabricDataOutput output,
CompletableFuture<HolderLookup.Provider> registriesFuture
) {
super(output, Registries.BIOME, registriesFuture);
}
public static void bootstrap(BootstapContext<Biome> bootstrapContext) {
BCLib.LOGGER.info("Bootstrap Biomes");
if (BCLibDatagen.ADD_TESTS && BCLib.isDevEnvironment()) {
THE_YELLOW = THE_YELLOW.register(bootstrapContext);
THE_BLUE = THE_BLUE.register(bootstrapContext);
BCLBiome theGray = BCLBiomeBuilder
.start(BCLib.makeID("the_gray"))
@ -93,4 +116,14 @@ public class TestBiomes {
.register(bootstrapContext).biome();
}
}
@Override
protected void addTags(HolderLookup.Provider arg) {
TagManager.BIOMES.forEachTag((tag, locs, tags) -> {
final FabricTagProvider<Biome>.FabricTagBuilder builder = getOrCreateTagBuilder(tag);
locs.forEach(builder::add);
tags.forEach(builder::addTag);
});
}
}

View file

@ -0,0 +1,159 @@
package org.betterx.datagen.bclib.tests;
import org.betterx.bclib.BCLib;
import org.betterx.bclib.util.MHelper;
import org.betterx.worlds.together.tag.v3.TagManager;
import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderSet;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.levelgen.GenerationStep;
import net.minecraft.world.level.levelgen.Heightmap;
import net.minecraft.world.level.levelgen.RandomState;
import net.minecraft.world.level.levelgen.structure.*;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceSerializationContext;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePieceType;
import net.minecraft.world.level.levelgen.structure.pieces.StructurePiecesBuilder;
import java.util.Map;
import java.util.Optional;
class TestStructurePiece extends StructurePiece {
static final ResourceKey<StructurePieceType> KEY = ResourceKey.create(
Registries.STRUCTURE_PIECE,
BCLib.makeID("test_piece")
);
static final StructurePieceType INSTANCE = TestStructurePiece::new;
protected TestStructurePiece(int genDepth, BoundingBox boundingBox) {
super(INSTANCE, genDepth, boundingBox);
}
public TestStructurePiece(CompoundTag compoundTag) {
super(INSTANCE, compoundTag);
}
public TestStructurePiece(
StructurePieceSerializationContext context,
CompoundTag tag
) {
super(INSTANCE, tag);
}
@Override
protected void addAdditionalSaveData(
StructurePieceSerializationContext structurePieceSerializationContext,
CompoundTag compoundTag
) {
}
@Override
public void postProcess(
WorldGenLevel worldGenLevel,
StructureManager structureManager,
ChunkGenerator chunkGenerator,
RandomSource randomSource,
BoundingBox boundingBox,
ChunkPos chunkPos,
BlockPos blockPos
) {
}
}
public class TestStructure extends Structure {
static final TagKey<Biome> TEST_STRUCTURE_TAG = TagManager.BIOMES.makeTag(BCLib.makeID("test_structure"));
static final ResourceKey<StructureType<?>> TYPE_KEY = ResourceKey.create(
Registries.STRUCTURE_TYPE,
BCLib.makeID("test_type")
);
static final StructureType<TestStructure> TYPE = () -> Structure.simpleCodec(TestStructure::new);
static final ResourceKey<Structure> KEY = ResourceKey.create(Registries.STRUCTURE, BCLib.makeID("test_structure"));
protected TestStructure(StructureSettings structureSettings) {
super(structureSettings);
}
@Override
protected Optional<GenerationStub> findGenerationPoint(GenerationContext context) {
BlockPos pos = getGenerationHeight(
context.chunkPos(),
context.chunkGenerator(),
context.heightAccessor(),
context.randomState()
);
if (pos.getY() >= 10) {
return Optional.of(new Structure.GenerationStub(pos, (structurePiecesBuilder) -> {
generatePieces(structurePiecesBuilder, context);
}));
}
return Optional.empty();
}
private static BlockPos getGenerationHeight(
ChunkPos chunkPos,
ChunkGenerator chunkGenerator,
LevelHeightAccessor levelHeightAccessor,
RandomState rState
) {
final int blockX = chunkPos.getBlockX(7);
final int blockZ = chunkPos.getBlockZ(7);
int z = chunkGenerator.getFirstOccupiedHeight(
blockX, blockZ, Heightmap.Types.WORLD_SURFACE_WG, levelHeightAccessor, rState
);
return new BlockPos.MutableBlockPos(blockX, z, blockZ);
}
protected void generatePieces(StructurePiecesBuilder structurePiecesBuilder, GenerationContext context) {
final RandomSource random = context.random();
final ChunkPos chunkPos = context.chunkPos();
final ChunkGenerator chunkGenerator = context.chunkGenerator();
final LevelHeightAccessor levelHeightAccessor = context.heightAccessor();
final RandomState rState = context.randomState();
int x = chunkPos.getBlockX(MHelper.randRange(4, 12, random));
int z = chunkPos.getBlockZ(MHelper.randRange(4, 12, random));
int y = chunkGenerator.getBaseHeight(x, z, Heightmap.Types.WORLD_SURFACE_WG, levelHeightAccessor, rState);
if (y > 50) {
structurePiecesBuilder.addPiece(new TestStructurePiece(
5,
new BoundingBox(x - 1, y - 1, z - 1, x + 1, y + 1, z + 1)
));
}
}
@Override
public StructureType<?> type() {
return TYPE;
}
public static void bootstrap(BootstapContext<Structure> bootstrapContext) {
BCLib.LOGGER.info("Bootstrap Structure");
Registry.register(BuiltInRegistries.STRUCTURE_PIECE, TestStructurePiece.KEY, TestStructurePiece.INSTANCE);
Registry.register(BuiltInRegistries.STRUCTURE_TYPE, TYPE_KEY, TYPE);
HolderSet<Biome> biomes = bootstrapContext.lookup(Registries.BIOME).getOrThrow(TEST_STRUCTURE_TAG);
bootstrapContext.register(KEY, new TestStructure(new Structure.StructureSettings(
biomes,
Map.of(),
GenerationStep.Decoration.SURFACE_STRUCTURES,
TerrainAdjustment.BEARD_THIN
)));
}
}

View file

@ -11,6 +11,7 @@ import com.mojang.serialization.Encoder;
import com.mojang.serialization.JsonOps;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.CachedOutput;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
@ -18,6 +19,7 @@ import net.minecraft.data.registries.VanillaRegistries;
import net.minecraft.resources.RegistryDataLoader;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.levelgen.structure.Structure;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
@ -35,7 +37,8 @@ public class BCLibRegistriesDataProvider implements DataProvider {
new RegistryDataLoader.RegistryData<>(
SurfaceRuleRegistry.SURFACE_RULES_REGISTRY,
AssignedSurfaceRule.CODEC
)
),
new RegistryDataLoader.RegistryData<>(Registries.STRUCTURE, Structure.DIRECT_CODEC)
//new RegistryDataLoader.RegistryData<>(Registries.WORLD_PRESET, WorldPreset.DIRECT_CODEC)
// new RegistryDataLoader.RegistryData<>(Registries.BIOME, Biome.DIRECT_CODEC),
// new RegistryDataLoader.RegistryData<>(Registries.CONFIGURED_FEATURE, ConfiguredFeature.DIRECT_CODEC),

View file

@ -25,6 +25,7 @@ public class WorldgenRegistriesDataProvider extends FabricDynamicRegistryProvide
entries.addAll(registries.lookupOrThrow(Registries.WORLD_PRESET));
entries.addAll(registries.lookupOrThrow(BCLBiomeRegistry.BCL_BIOMES_REGISTRY));
entries.addAll(registries.lookupOrThrow(SurfaceRuleRegistry.SURFACE_RULES_REGISTRY));
entries.addAll(registries.lookupOrThrow(Registries.STRUCTURE));
}
@Override

View file

@ -1,5 +1,6 @@
package org.betterx.worlds.together.tag.v3;
import org.betterx.bclib.interfaces.TriConsumer;
import org.betterx.worlds.together.WorldsTogether;
import net.minecraft.core.DefaultedRegistry;
@ -12,6 +13,7 @@ import net.minecraft.tags.TagEntry;
import net.minecraft.tags.TagKey;
import net.minecraft.tags.TagLoader;
import net.minecraft.tags.TagManager;
import net.minecraft.util.ExtraCodecs;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.biome.Biome;
@ -20,10 +22,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
@ -50,12 +49,13 @@ public class TagRegistry<T> {
@Override
public TagKey<T> makeTag(ResourceLocation id) {
initializeTag(id);
return registry
final TagKey<T> tag = registry
.getTagNames()
.filter(tagKey -> tagKey.location().equals(id))
.findAny()
.orElse(TagKey.create(registry.key(), id));
initializeTag(tag);
return tag;
}
}
@ -141,7 +141,7 @@ public class TagRegistry<T> {
}
public final String directory;
private final Map<ResourceLocation, Set<TagEntry>> tags = Maps.newConcurrentMap();
private final Map<TagKey<T>, Set<TagEntry>> tags = Maps.newConcurrentMap();
public final ResourceKey<? extends Registry<T>> registryKey;
private final Function<T, ResourceLocation> locationProvider;
@ -155,19 +155,16 @@ public class TagRegistry<T> {
this.locationProvider = locationProvider;
}
protected void initializeTag(ResourceLocation tagID) {
getSetForTag(tagID);
protected void initializeTag(TagKey<T> tag) {
getSetForTag(tag);
}
public Set<TagEntry> getSetForTag(ResourceLocation tagID) {
return tags.computeIfAbsent(tagID, k -> Sets.newHashSet());
}
public Set<TagEntry> getSetForTag(TagKey<T> tag) {
if (tag == null) {
return new HashSet<>();
}
return getSetForTag(tag.location());
return tags.computeIfAbsent(tag, k -> Sets.newHashSet());
}
/**
@ -192,8 +189,9 @@ public class TagRegistry<T> {
}
protected TagKey<T> creatTagKey(ResourceLocation id) {
initializeTag(id);
return TagKey.create(registryKey, id);
final TagKey<T> tag = TagKey.create(registryKey, id);
initializeTag(tag);
return tag;
}
/**
@ -262,7 +260,25 @@ public class TagRegistry<T> {
}
public void forEach(BiConsumer<ResourceLocation, Set<TagEntry>> consumer) {
tags.forEach(consumer);
tags.forEach((a, b) -> consumer.accept(a.location(), b));
}
public void forEachTag(TriConsumer<TagKey<T>, List<ResourceLocation>, List<TagKey<T>>> consumer) {
tags.forEach((tag, set) -> {
List<ResourceLocation> locations = new LinkedList<>();
List<TagKey<T>> tags = new LinkedList<>();
set.forEach(e -> {
ExtraCodecs.TagOrElementLocation t = e.elementOrTag();
if (t.tag()) {
tags.add(TagKey.create(registryKey, t.id()));
} else {
locations.add(t.id());
}
});
consumer.accept(tag, locations, tags);
});
}
public void apply(Map<ResourceLocation, List<TagLoader.EntryWithSource>> tagsMap) {

View file

@ -25,5 +25,7 @@ accessible method net/minecraft/world/level/block/state/properties/WoodType regi
accessible method net/minecraft/world/level/levelgen/NoiseRouterData nether (Lnet/minecraft/core/HolderGetter;Lnet/minecraft/core/HolderGetter;)Lnet/minecraft/world/level/levelgen/NoiseRouter;
accessible method net/minecraft/world/level/levelgen/NoiseRouterData noNewCaves (Lnet/minecraft/core/HolderGetter;Lnet/minecraft/core/HolderGetter;Lnet/minecraft/world/level/levelgen/DensityFunction;)Lnet/minecraft/world/level/levelgen/NoiseRouter;
accessible method net/minecraft/world/level/levelgen/NoiseRouterData slideNetherLike (Lnet/minecraft/core/HolderGetter;II)Lnet/minecraft/world/level/levelgen/DensityFunction;
accessible method net/minecraft/tags/TagEntry elementOrTag ()Lnet/minecraft/util/ExtraCodecs$TagOrElementLocation;
#Fields
accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map;