mirror of
https://github.com/FabricMC/fabric.git
synced 2025-03-23 21:40:02 -04:00
1.18.2-pre1 Biome API (#2010)
* Fix BiomeSelectors.tag * Update fabric-biome-api-v1/src/main/java/net/fabricmc/fabric/api/biome/v1/BiomeSelectionContext.java Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com> * Checkstyle * Port Biome API Co-authored-by: Juuxel <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
parent
d1027f7d5e
commit
58afd26713
12 changed files with 38 additions and 279 deletions
fabric-biome-api-v1/src
main
java/net/fabricmc/fabric
api/biome/v1
impl/biome
resources
testmod/java/net/fabricmc/fabric/test/biome
|
@ -21,7 +21,6 @@ import java.util.function.BiPredicate;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.sound.BiomeAdditionsSound;
|
||||
|
@ -36,8 +35,7 @@ import net.minecraft.world.biome.BiomeParticleConfig;
|
|||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
|
@ -393,67 +391,6 @@ public interface BiomeModificationContext {
|
|||
default boolean removeBuiltInCarver(GenerationStep.Carver step, ConfiguredCarver<?> configuredCarver) {
|
||||
return removeCarver(step, BuiltInRegistryKeys.get(configuredCarver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows a configured structure to start in this biome.
|
||||
*
|
||||
* <p>Structures added this way may start in this biome, with respect to the {@link net.minecraft.world.gen.chunk.StructureConfig}
|
||||
* set in the {@link net.minecraft.world.gen.chunk.ChunkGenerator}, but structure pieces can always generate in chunks adjacent
|
||||
* to a started structure, regardless of biome.
|
||||
*
|
||||
* <p>Configured structures that have the same underlying {@link StructureFeature} as the given structure will be removed before
|
||||
* adding the new structure, since only one of them could actually generate.
|
||||
*
|
||||
* @see net.minecraft.world.biome.GenerationSettings.Builder#feature(GenerationStep.Feature, PlacedFeature)
|
||||
*/
|
||||
void addStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey);
|
||||
|
||||
/**
|
||||
* Allows a configured structure from {@link BuiltinRegistries#CONFIGURED_STRUCTURE_FEATURE} to start in this biome.
|
||||
*
|
||||
* <p>This method is intended for use with the configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
|
||||
*
|
||||
* <p><b>NOTE:</b> In case the configured structure is overridden using a datapack, the definition from the datapack
|
||||
* will be added to the biome.
|
||||
*
|
||||
* <p>Structures added this way may start in this biome, with respect to the {@link net.minecraft.world.gen.chunk.StructureConfig}
|
||||
* set in the {@link net.minecraft.world.gen.chunk.ChunkGenerator}, but structure pieces can always generate in chunks adjacent
|
||||
* to a started structure, regardless of biome.
|
||||
*
|
||||
* <p>Configured structures that have the same underlying {@link StructureFeature} as the given structure will be removed before
|
||||
* adding the new structure, since only one of them could actually generate.
|
||||
*/
|
||||
default void addBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
addStructure(BuiltInRegistryKeys.get(configuredStructure));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a configured structure from the structures that are allowed to start in this biome.
|
||||
*
|
||||
* <p>Please see the note on {@link #addStructure(RegistryKey)} about structures pieces still generating
|
||||
* if adjacent biomes allow the structure to start.
|
||||
*
|
||||
* @return True if any structures were removed.
|
||||
*/
|
||||
boolean removeStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey);
|
||||
|
||||
/**
|
||||
* Removes a structure from the structures that are allowed to start in this biome.
|
||||
*
|
||||
* <p>This will remove all configured variations of the given structure from this biome.
|
||||
*
|
||||
* <p>This can be used with modded structures or Vanilla structures from {@link net.minecraft.world.gen.feature.StructureFeature}.
|
||||
*
|
||||
* @return True if any structures were removed.
|
||||
*/
|
||||
boolean removeStructure(StructureFeature<?> structure);
|
||||
|
||||
/**
|
||||
* {@link #removeStructure(RegistryKey)} for built-in structures (see {@link #addBuiltInStructure(ConfiguredStructureFeature)}).
|
||||
*/
|
||||
default boolean removeBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
return removeStructure(BuiltInRegistryKeys.get(configuredStructure));
|
||||
}
|
||||
}
|
||||
|
||||
interface SpawnSettingsContext {
|
||||
|
|
|
@ -28,7 +28,6 @@ import net.minecraft.util.registry.RegistryKey;
|
|||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
||||
/**
|
||||
|
@ -51,17 +50,6 @@ public final class BiomeModifications {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to add a structure to one or more biomes.
|
||||
*
|
||||
* @see BiomeSelectors
|
||||
*/
|
||||
public static void addStructure(Predicate<BiomeSelectionContext> biomeSelector, RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
|
||||
create(configuredStructureKey.getValue()).add(ModificationPhase.ADDITIONS, biomeSelector, context -> {
|
||||
context.getGenerationSettings().addStructure(configuredStructureKey);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to add a carver to one or more biomes.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,7 @@ package net.fabricmc.fabric.api.biome.v1;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryEntryList;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
|
@ -41,6 +42,8 @@ public interface BiomeSelectionContext {
|
|||
*/
|
||||
Biome getBiome();
|
||||
|
||||
RegistryEntry<Biome> getBiomeRegistryEntry();
|
||||
|
||||
/**
|
||||
* Returns true if this biome has the given configured feature, which must be registered
|
||||
* in the {@link net.minecraft.util.registry.BuiltinRegistries}.
|
||||
|
@ -118,16 +121,16 @@ public interface BiomeSelectionContext {
|
|||
*
|
||||
* <p>This method is intended for use with the Vanilla configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
|
||||
*/
|
||||
default boolean hasBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
default boolean validForBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
|
||||
RegistryKey<ConfiguredStructureFeature<?, ?>> key = BuiltInRegistryKeys.get(configuredStructure);
|
||||
return hasStructure(key);
|
||||
return validForStructure(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the configured structure with the given key can start in this biome in any chunk generator
|
||||
* used by the current world-save.
|
||||
*/
|
||||
boolean hasStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
|
||||
boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
|
||||
|
||||
/**
|
||||
* Tries to retrieve the registry key for the given configured feature, which should be from this biomes
|
||||
|
@ -143,4 +146,9 @@ public interface BiomeSelectionContext {
|
|||
* <p>If no dimension options exist for the given dimension key, <code>false</code> is returned.
|
||||
*/
|
||||
boolean canGenerateIn(RegistryKey<DimensionOptions> dimensionKey);
|
||||
|
||||
/**
|
||||
* {@return true if this biome is in the given {@link TagKey}}.
|
||||
*/
|
||||
boolean hasTag(TagKey<Biome> tag);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ public final class BiomeSelectors {
|
|||
* @see net.fabricmc.fabric.api.tag.TagFactory#BIOME
|
||||
*/
|
||||
public static Predicate<BiomeSelectionContext> tag(TagKey<Biome> tag) {
|
||||
return context -> BuiltinRegistries.BIOME.containsTag(tag);
|
||||
return context -> context.hasTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -60,7 +60,7 @@ public final class NetherBiomeData {
|
|||
if (NETHER_BIOMES.isEmpty()) {
|
||||
MultiNoiseBiomeSource source = MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(BuiltinRegistries.BIOME);
|
||||
|
||||
for (RegistryEntry<Biome> entry : source.getBiomes().toList()) {
|
||||
for (RegistryEntry<Biome> entry : source.getBiomes()) {
|
||||
BuiltinRegistries.BIOME.getKey(entry.value()).ifPresent(NETHER_BIOMES::add);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,6 @@ import net.minecraft.world.gen.carver.ConfiguredCarver;
|
|||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
|
||||
|
||||
|
@ -322,25 +321,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
|
||||
ConfiguredStructureFeature<?, ?> configuredStructure = structures.getOrThrow(configuredStructureKey);
|
||||
|
||||
BiomeStructureStartsImpl.addStart(registries, configuredStructure, biomeKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey) {
|
||||
ConfiguredStructureFeature<?, ?> configuredStructure = structures.getOrThrow(configuredStructureKey);
|
||||
|
||||
return BiomeStructureStartsImpl.removeStart(registries, configuredStructure, biomeKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeStructure(StructureFeature<?> structure) {
|
||||
return BiomeStructureStartsImpl.removeStructureStarts(registries, structure, biomeKey);
|
||||
}
|
||||
|
||||
private <T> RegistryEntryList<T> plus(RegistryEntryList<T> values, RegistryEntry<T> entry) {
|
||||
List<RegistryEntry<T>> list = new ArrayList<>(values.stream().toList());
|
||||
list.add(entry);
|
||||
|
|
|
@ -120,7 +120,7 @@ public class BiomeModificationImpl {
|
|||
|
||||
// Build a list of all biome keys in ascending order of their raw-id to get a consistent result in case
|
||||
// someone does something stupid.
|
||||
List<RegistryKey<Biome>> keys = biomes.getEntries().stream()
|
||||
List<RegistryKey<Biome>> keys = biomes.getEntrySet().stream()
|
||||
.map(Map.Entry::getKey)
|
||||
.sorted(Comparator.comparingInt(key -> biomes.getRawId(biomes.getOrThrow(key))))
|
||||
.toList();
|
||||
|
@ -170,7 +170,7 @@ public class BiomeModificationImpl {
|
|||
BiomeSource biomeSource = dimension.getChunkGenerator().getBiomeSource();
|
||||
|
||||
// Replace the Supplier to force it to rebuild on next call
|
||||
biomeSource.field_34469 = Suppliers.memoize(() -> {
|
||||
biomeSource.indexedFeaturesSupplier = Suppliers.memoize(() -> {
|
||||
return biomeSource.method_39525(biomeSource.biomes.stream().map(RegistryEntry::value).toList(), true);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -20,12 +20,13 @@ import java.util.Optional;
|
|||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.dimension.DimensionOptions;
|
||||
import net.minecraft.world.gen.chunk.placement.StructuresConfig;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
@ -39,12 +40,14 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
private final LevelProperties levelProperties;
|
||||
private final RegistryKey<Biome> key;
|
||||
private final Biome biome;
|
||||
private final RegistryEntry<Biome> entry;
|
||||
|
||||
public BiomeSelectionContextImpl(DynamicRegistryManager dynamicRegistries, LevelProperties levelProperties, RegistryKey<Biome> key, Biome biome) {
|
||||
this.dynamicRegistries = dynamicRegistries;
|
||||
this.levelProperties = levelProperties;
|
||||
this.key = key;
|
||||
this.biome = biome;
|
||||
this.entry = dynamicRegistries.get(Registry.BIOME_KEY).getEntry(this.key).orElseThrow();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -57,6 +60,11 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
return biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RegistryEntry<Biome> getBiomeRegistryEntry() {
|
||||
return entry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RegistryKey<ConfiguredFeature<?, ?>>> getFeatureKey(ConfiguredFeature<?, ?> configuredFeature) {
|
||||
Registry<ConfiguredFeature<?, ?>> registry = dynamicRegistries.get(Registry.CONFIGURED_FEATURE_KEY);
|
||||
|
@ -70,24 +78,14 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean hasStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
|
||||
public boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
|
||||
ConfiguredStructureFeature<?, ?> instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
|
||||
|
||||
if (instance == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since the biome->structure mapping is now stored in the chunk generator configuration, we check every
|
||||
// chunk generator used by the current world-save.
|
||||
for (DimensionOptions dimension : levelProperties.getGeneratorOptions().getDimensions()) {
|
||||
StructuresConfig structuresConfig = dimension.getChunkGenerator().getStructuresConfig();
|
||||
|
||||
if (structuresConfig.getConfiguredStructureFeature(instance.feature).get(key).contains(getBiomeKey())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return instance.getBiomes().contains(getBiomeRegistryEntry());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,6 +102,12 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
|
|||
return false;
|
||||
}
|
||||
|
||||
return dimension.getChunkGenerator().getBiomeSource().getBiomes().anyMatch(entry -> entry.value() == biome);
|
||||
return dimension.getChunkGenerator().getBiomeSource().getBiomes().stream().anyMatch(entry -> entry.value() == biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTag(TagKey<Biome> tag) {
|
||||
Registry<Biome> biomeRegistry = dynamicRegistries.get(Registry.BIOME_KEY);
|
||||
return biomeRegistry.entryOf(getBiomeKey()).isIn(tag);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.impl.biome.modification;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
|
||||
import net.minecraft.world.gen.feature.StructureFeature;
|
||||
|
||||
/**
|
||||
* Helps with modifying the structure start information stored in {@link ChunkGeneratorSettings}.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class BiomeStructureStartsImpl {
|
||||
private BiomeStructureStartsImpl() {
|
||||
}
|
||||
|
||||
public static void addStart(
|
||||
DynamicRegistryManager registries,
|
||||
ConfiguredStructureFeature<?, ?> configuredStructure,
|
||||
RegistryKey<Biome> biome
|
||||
) {
|
||||
changeStructureStarts(registries, structureMap -> {
|
||||
Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.computeIfAbsent(configuredStructure.feature, k -> HashMultimap.create());
|
||||
|
||||
// This is tricky, the keys might be either from builtin (Vanilla) or dynamic registries (modded)
|
||||
RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure).orElseThrow();
|
||||
RegistryKey<ConfiguredStructureFeature<?, ?>> mapKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure)
|
||||
.orElse(configuredStructureKey);
|
||||
|
||||
// orElse means the configured structure passed in is not a (potentially modified) Vanilla entry,
|
||||
// but rather a modded one. In this case, this will create a new entry in the map.
|
||||
configuredMap.put(mapKey, biome);
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean removeStart(
|
||||
DynamicRegistryManager registries,
|
||||
ConfiguredStructureFeature<?, ?> configuredStructure,
|
||||
RegistryKey<Biome> biome
|
||||
) {
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
|
||||
changeStructureStarts(registries, structureMap -> {
|
||||
Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.get(configuredStructure.feature);
|
||||
|
||||
if (configuredMap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is tricky, the keys might be either from builtin (Vanilla) or dynamic registries (modded)
|
||||
RegistryKey<ConfiguredStructureFeature<?, ?>> configuredStructureKey = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).getKey(configuredStructure).orElseThrow();
|
||||
ConfiguredStructureFeature<?, ?> mapKey = BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.get(configuredStructureKey);
|
||||
|
||||
if (mapKey == null) {
|
||||
// This means the configured structure passed in is not a (potentially modified) Vanilla entry,
|
||||
// but rather a modded one. In this case, this will create a new entry in the map.
|
||||
mapKey = configuredStructure;
|
||||
}
|
||||
|
||||
if (configuredMap.remove(mapKey, biome)) {
|
||||
result.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
public static boolean removeStructureStarts(
|
||||
DynamicRegistryManager registries,
|
||||
StructureFeature<?> structure,
|
||||
RegistryKey<Biome> biome
|
||||
) {
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
|
||||
changeStructureStarts(registries, structureMap -> {
|
||||
Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>> configuredMap = structureMap.get(structure);
|
||||
|
||||
if (configuredMap == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (configuredMap.values().remove(biome)) {
|
||||
result.set(true);
|
||||
}
|
||||
});
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private static void changeStructureStarts(DynamicRegistryManager registries, Consumer<Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>>> modifier) {
|
||||
Registry<ChunkGeneratorSettings> chunkGenSettingsRegistry = registries.get(Registry.CHUNK_GENERATOR_SETTINGS_KEY);
|
||||
|
||||
for (Map.Entry<RegistryKey<ChunkGeneratorSettings>, ChunkGeneratorSettings> entry : chunkGenSettingsRegistry.getEntries()) {
|
||||
Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> structureMap = unfreeze(entry.getValue());
|
||||
|
||||
modifier.accept(structureMap);
|
||||
|
||||
freeze(entry.getValue(), structureMap);
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> unfreeze(ChunkGeneratorSettings settings) {
|
||||
ImmutableMap<StructureFeature<?>, ImmutableMultimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> frozenMap = settings.getStructuresConfig().configuredStructures;
|
||||
Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> result = new HashMap<>(frozenMap.size());
|
||||
|
||||
for (Map.Entry<StructureFeature<?>, ImmutableMultimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> entry : frozenMap.entrySet()) {
|
||||
result.put(entry.getKey(), HashMultimap.create(entry.getValue()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void freeze(ChunkGeneratorSettings settings, Map<StructureFeature<?>, Multimap<RegistryKey<ConfiguredStructureFeature<?, ?>>, RegistryKey<Biome>>> structureStarts) {
|
||||
settings.getStructuresConfig().configuredStructures = structureStarts.entrySet().stream()
|
||||
.collect(ImmutableMap.toImmutableMap(
|
||||
Map.Entry::getKey,
|
||||
e -> ImmutableMultimap.copyOf(e.getValue())
|
||||
));
|
||||
}
|
||||
}
|
|
@ -4,8 +4,8 @@ accessible class net/minecraft/world/biome/Biome$Weather
|
|||
# Rebuilding biome source feature lists
|
||||
accessible method net/minecraft/world/biome/source/BiomeSource method_39525 (Ljava/util/List;Z)Ljava/util/List;
|
||||
accessible field net/minecraft/world/biome/source/BiomeSource biomes Ljava/util/Set;
|
||||
accessible field net/minecraft/world/biome/source/BiomeSource field_34469 Ljava/util/function/Supplier;
|
||||
mutable field net/minecraft/world/biome/source/BiomeSource field_34469 Ljava/util/function/Supplier;
|
||||
accessible field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSupplier Ljava/util/function/Supplier;
|
||||
mutable field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSupplier Ljava/util/function/Supplier;
|
||||
|
||||
# Top-Level Biome Fields Access
|
||||
accessible field net/minecraft/world/biome/Biome weather Lnet/minecraft/world/biome/Biome$Weather;
|
||||
|
|
|
@ -83,14 +83,6 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
Registry.register(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands());
|
||||
Registry.register(BuiltinRegistries.BIOME, TEST_END_BARRRENS.getValue(), createEndBarrens());
|
||||
|
||||
BiomeModifications.create(new Identifier("fabric:end_test_structures"))
|
||||
.add(ModificationPhase.ADDITIONS, BiomeSelectors.includeByKey(TEST_END_HIGHLANDS, TEST_END_MIDLANDS), ctx -> {
|
||||
ctx.getGenerationSettings().addStructure(RegistryKey.of(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY, new Identifier("end_city")));
|
||||
})
|
||||
.add(ModificationPhase.ADDITIONS, BiomeSelectors.includeByKey(BiomeKeys.PLAINS), ctx -> {
|
||||
ctx.getGenerationSettings().addStructure(RegistryKey.of(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY, new Identifier("end_city")));
|
||||
});
|
||||
|
||||
// TESTING HINT: to get to the end:
|
||||
// /execute in minecraft:the_end run tp @s 0 90 0
|
||||
TheEndBiomes.addHighlandsBiome(TEST_END_HIGHLANDS, 5.0);
|
||||
|
@ -117,7 +109,7 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
);
|
||||
})
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.tag(TagKey.intern(Registry.BIOME_KEY, new Identifier(MOD_ID, "tag_selector_test"))),
|
||||
BiomeSelectors.tag(TagKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "tag_selector_test"))),
|
||||
context -> context.getEffects().setSkyColor(0x770000));
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ rootProject.name = "fabric-api"
|
|||
include 'fabric-api-base'
|
||||
|
||||
include 'fabric-api-lookup-api-v1'
|
||||
//include 'fabric-biome-api-v1'
|
||||
include 'fabric-biome-api-v1'
|
||||
include 'fabric-blockrenderlayer-v1'
|
||||
include 'fabric-commands-v0'
|
||||
include 'fabric-command-api-v1'
|
||||
|
|
Loading…
Add table
Reference in a new issue