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 com.google.common.collect.ImmutableList;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.chunk.StructureConfig; import net.minecraft.world.gen.chunk.StructureConfig;
import net.minecraft.world.gen.chunk.StructuresConfig; 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.FeatureConfig;
import net.minecraft.world.gen.feature.StructureFeature; import net.minecraft.world.gen.feature.StructureFeature;
import net.fabricmc.fabric.impl.structure.FabricStructureImpl; import net.fabricmc.fabric.impl.structure.FabricStructureImpl;
import net.fabricmc.fabric.mixin.structure.FlatChunkGeneratorConfigAccessor;
import net.fabricmc.fabric.mixin.structure.StructureFeatureAccessor; 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 final S structure;
private GenerationStep.Feature step; private GenerationStep.Feature step;
private StructureConfig defaultConfig; private StructureConfig defaultConfig;
private ConfiguredStructureFeature<FC, ? extends StructureFeature<FC>> superflatFeature; private boolean generateInSuperflat = false;
private boolean adjustsSurface = false; private boolean adjustsSurface = false;
private FabricStructureBuilder(Identifier id, S structure) { private FabricStructureBuilder(Identifier id, S structure) {
@ -117,7 +115,6 @@ public final class FabricStructureBuilder<FC extends FeatureConfig, S extends St
* @param separation The minimum distance between 2 structures of this type. * @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 * @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. * structure must have an unique {@code salt} in order to spawn in different places.
*
* @see #defaultConfig(StructureConfig) * @see #defaultConfig(StructureConfig)
*/ */
public FabricStructureBuilder<FC, S> defaultConfig(int spacing, int separation, int salt) { 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 * Enables generation of this feature in superflat worlds. Structures will still only generate in biomes
* superflat worlds. * for which they have been enabled. Superflat worlds will use the plains biome by default.
*
* @see #superflatFeature(FeatureConfig)
*/ */
public FabricStructureBuilder<FC, S> superflatFeature(ConfiguredStructureFeature<FC, ? extends StructureFeature<FC>> superflatFeature) { public FabricStructureBuilder<FC, S> enableSuperflat() {
Objects.requireNonNull(superflatFeature, "superflatFeature must not be null"); this.generateInSuperflat = true;
this.superflatFeature = superflatFeature;
return this; 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 * 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. * 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); FabricStructureImpl.STRUCTURE_TO_CONFIG_MAP.put(structure, defaultConfig);
if (superflatFeature != null) { if (generateInSuperflat) {
FlatChunkGeneratorConfigAccessor.getStructureToFeatures().put(structure, superflatFeature); FabricStructureImpl.FLAT_STRUCTURE_TO_CONFIG_MAP.put(structure, defaultConfig);
} }
if (adjustsSurface) { if (adjustsSurface) {

View file

@ -29,6 +29,9 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.fabricmc.fabric.mixin.structure.StructuresConfigAccessor; import net.fabricmc.fabric.mixin.structure.StructuresConfigAccessor;
public class FabricStructureImpl implements ModInitializer { 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. //Keeps a map of structures to structure configs.
public static final Map<StructureFeature<?>, StructureConfig> STRUCTURE_TO_CONFIG_MAP = new HashMap<>(); public static final Map<StructureFeature<?>, StructureConfig> STRUCTURE_TO_CONFIG_MAP = new HashMap<>();

View file

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

View file

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

View file

@ -61,7 +61,7 @@ public class StructureTest {
FabricStructureBuilder.create(new Identifier("fabric", "test_structure"), STRUCTURE) FabricStructureBuilder.create(new Identifier("fabric", "test_structure"), STRUCTURE)
.step(GenerationStep.Feature.SURFACE_STRUCTURES) .step(GenerationStep.Feature.SURFACE_STRUCTURES)
.defaultConfig(32, 8, 12345) .defaultConfig(32, 8, 12345)
.superflatFeature(CONFIGURED_STRUCTURE) .enableSuperflat()
.adjustsSurface() .adjustsSurface()
.register(); .register();
Registry.register(Registry.STRUCTURE_PIECE, new Identifier("fabric", "test_structure_piece"), PIECE); 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) @Mixin(ConfiguredStructureFeatures.class)
public class MixinConfiguredStructureFeatures { 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) { private static void addStructuresToBiomes(BiConsumer<ConfiguredStructureFeature<?, ?>, RegistryKey<Biome>> consumer, CallbackInfo ci) {
consumer.accept(StructureTest.CONFIGURED_STRUCTURE, BiomeKeys.PLAINS); consumer.accept(StructureTest.CONFIGURED_STRUCTURE, BiomeKeys.PLAINS);
} }