Fixes the structure API for 1.18. (#1730)

Structures are no longer linked to Biomes via an instance field  in the Biome class. Instead they are linked by registry keys. This means that standard biome spawning rules also apply to superflat worlds, instead of the hardcoded list of structures linked with superflat worlds by default. Changes the FabricStructureBuilder to allow adding structures to this default list.
This commit is contained in:
shartte 2021-09-19 10:06:27 +02:00 committed by GitHub
parent dc466edebd
commit fb712d3a80
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 29 additions and 40 deletions

View file

@ -20,16 +20,14 @@ import java.util.Objects;
import com.google.common.collect.ImmutableList;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.util.Identifier;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.chunk.StructureConfig;
import net.minecraft.world.gen.chunk.StructuresConfig;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature;
import net.fabricmc.fabric.impl.structure.FabricStructureImpl;
import net.fabricmc.fabric.mixin.structure.FlatChunkGeneratorConfigAccessor;
import net.fabricmc.fabric.mixin.structure.StructureFeatureAccessor;
/**
@ -55,7 +53,7 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
private final S structure;
private GenerationStep.Feature step;
private StructureConfig defaultConfig;
private ConfiguredStructureFeature<FC, ? extends StructureFeature<FC>> superflatFeature;
private boolean generateInSuperflat = false;
private boolean adjustsSurface = false;
private FabricStructureBuilder(Identifier id, S structure) {
@ -66,7 +64,7 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
/**
* Creates a new {@code FabricStructureBuilder} for registering a structure.
*
* @param id The structure ID.
* @param id The structure ID.
* @param structure The {@linkplain StructureFeature} you want to register.
*/
public static <FC extends FeatureConfig, S extends StructureFeature<FC>> FabricStructureBuilder<FC, S> create(Identifier id, S structure) {
@ -113,11 +111,10 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
*
* <p>This is a required option. Vanilla needs it to function.</p>
*
* @param spacing The average distance between 2 structures of this type along the X and Z axes.
* @param spacing The average distance between 2 structures of this type along the X and Z axes.
* @param separation The minimum distance between 2 structures of this type.
* @param salt The random salt of the structure. This does not affect how common the structure is, but every
* structure must have an unique {@code salt} in order to spawn in different places.
*
* @param salt The random salt of the structure. This does not affect how common the structure is, but every
* structure must have an unique {@code salt} in order to spawn in different places.
* @see #defaultConfig(StructureConfig)
*/
public FabricStructureBuilder<FC, S> defaultConfig(int spacing, int separation, int salt) {
@ -125,27 +122,14 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
}
/**
* Sets the structure configuration which spawns in superflat worlds. If unset, this structure will not spawn in
* superflat worlds.
*
* @see #superflatFeature(FeatureConfig)
* Enables generation of this feature in superflat worlds. Structures will still only generate in biomes
* for which they have been enabled. Superflat worlds will use the plains biome by default.
*/
public FabricStructureBuilder<FC, S> superflatFeature(ConfiguredStructureFeature<FC, ? extends StructureFeature<FC>> superflatFeature) {
Objects.requireNonNull(superflatFeature, "superflatFeature must not be null");
this.superflatFeature = superflatFeature;
public FabricStructureBuilder<FC, S> enableSuperflat() {
this.generateInSuperflat = true;
return this;
}
/**
* Sets the structure configuration which spawns in superflat worlds. If unset, this structure will not spawn in
* superflat worlds.
*
* @see #superflatFeature(ConfiguredStructureFeature)
*/
public FabricStructureBuilder<FC, S> superflatFeature(FC config) {
return superflatFeature(structure.configure(config));
}
/**
* Causes structure pieces of this structure to adjust the surface of the world to fit them, so that they don't
* stick out of or into the ground.
@ -174,8 +158,8 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.put(structure, defaultConfig);
if (superflatFeature != null) {
FlatChunkGeneratorConfigAccessor.getStructureToFeatures().put(structure, superflatFeature);
if (generateInSuperflat) {
FabricStructureImpl.FLAT_STRUCTURE_TO_CONFIG_MAP.put(structure, defaultConfig);
}
if (adjustsSurface) {

View file

@ -29,6 +29,9 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.mixin.structure.StructuresConfigAccessor;
public class FabricStructureImpl implements ModInitializer {
//Keeps a map of structures to structure configs for purposes of initializing the flat chunk generator
public static final Map<StructureFeature<?>, StructureConfig> FLAT_STRUCTURE_TO_CONFIG_MAP = new HashMap<>();
//Keeps a map of structures to structure configs.
public static final Map<StructureFeature<?>, StructureConfig> STRUCTURE_TO_CONFIG_MAP = new HashMap<>();

View file

@ -16,19 +16,21 @@
package net.fabricmc.fabric.mixin.structure;
import java.util.Map;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.world.gen.chunk.FlatChunkGeneratorConfig;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.gen.chunk.StructuresConfig;
import net.fabricmc.fabric.impl.structure.FabricStructureImpl;
@Mixin(FlatChunkGeneratorConfig.class)
public interface FlatChunkGeneratorConfigAccessor {
@Accessor("STRUCTURE_TO_FEATURES")
static Map<StructureFeature<?>, ConfiguredStructureFeature<?, ?>> getStructureToFeatures() {
throw new AssertionError("Untransformed accessor");
public class FlatChunkGeneratorConfigMixin {
@Inject(method = "getDefaultConfig", at = @At(value = "RETURN"))
private static void createDefaultConfig(CallbackInfoReturnable<FlatChunkGeneratorConfig> cir) {
StructuresConfig structuresConfig = cir.getReturnValue().getStructuresConfig();
structuresConfig.getStructures().putAll(FabricStructureImpl.FLAT_STRUCTURE_TO_CONFIG_MAP);
}
}

View file

@ -4,7 +4,7 @@
"compatibilityLevel": "JAVA_16",
"mixins": [
"ChunkSerializerMixin",
"FlatChunkGeneratorConfigAccessor",
"FlatChunkGeneratorConfigMixin",
"StructureFeatureAccessor",
"StructuresConfigAccessor"
],

View file

@ -61,7 +61,7 @@ public class StructureTest {
FabricStructureBuilder.create(new Identifier("fabric", "test_structure"), STRUCTURE)
.step(GenerationStep.Feature.SURFACE_STRUCTURES)
.defaultConfig(32, 8, 12345)
.superflatFeature(CONFIGURED_STRUCTURE)
.enableSuperflat()
.adjustsSurface()
.register();
Registry.register(Registry.STRUCTURE_PIECE, new Identifier("fabric", "test_structure_piece"), PIECE);

View file

@ -33,7 +33,7 @@ import net.fabricmc.fabric.test.structure.StructureTest;
@Mixin(ConfiguredStructureFeatures.class)
public class MixinConfiguredStructureFeatures {
@Inject(method = "method_38571", at = @At("TAIL"))
@Inject(method = "method_38570", at = @At("TAIL"))
private static void addStructuresToBiomes(BiConsumer<ConfiguredStructureFeature<?, ?>, RegistryKey<Biome>> consumer, CallbackInfo ci) {
consumer.accept(StructureTest.CONFIGURED_STRUCTURE, BiomeKeys.PLAINS);
}