mirror of
https://github.com/FabricMC/fabric.git
synced 2024-11-14 19:25:23 -05:00
22w44a (#2632)
Co-authored-by: Sebastian Hartte <shartte@users.noreply.github.com>
This commit is contained in:
parent
f5429c1aa0
commit
f75bcd18f3
54 changed files with 789 additions and 827 deletions
17
build.gradle
17
build.gradle
|
@ -408,24 +408,11 @@ subprojects {
|
|||
}
|
||||
}
|
||||
|
||||
task remapMavenJar(type: net.fabricmc.loom.task.RemapJarTask, dependsOn: jar) {
|
||||
input = jar.archiveFile
|
||||
archiveFileName = "${archivesBaseName}-${project.version}-maven.jar"
|
||||
addNestedDependencies = false
|
||||
}
|
||||
build.dependsOn remapMavenJar
|
||||
|
||||
if (signingEnabled) {
|
||||
remoteSign {
|
||||
sign remapMavenJar
|
||||
}
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact(signingEnabled ? signRemapMavenJar.output : remapMavenJar) {
|
||||
builtBy(signingEnabled ? signRemapMavenJar : remapMavenJar)
|
||||
artifact(signingEnabled ? signRemapJar.output : remapJar) {
|
||||
builtBy(signingEnabled ? signRemapJar : remapJar)
|
||||
}
|
||||
|
||||
artifact(sourcesJar) {
|
||||
|
|
|
@ -27,7 +27,6 @@ import net.minecraft.sound.BiomeAdditionsSound;
|
|||
import net.minecraft.sound.BiomeMoodSound;
|
||||
import net.minecraft.sound.MusicSound;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeEffects;
|
||||
|
@ -37,8 +36,6 @@ import net.minecraft.world.gen.GenerationStep;
|
|||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
/**
|
||||
* Allows {@link Biome} properties to be modified.
|
||||
*
|
||||
|
@ -297,57 +294,16 @@ public interface BiomeModificationContext {
|
|||
return anyFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #removeFeature(RegistryKey)} for built-in features (see {@link #addBuiltInFeature(GenerationStep.Feature, PlacedFeature)}).
|
||||
*/
|
||||
default boolean removeBuiltInFeature(PlacedFeature placedFeature) {
|
||||
return removeFeature(BuiltInRegistryKeys.get(placedFeature));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #removeFeature(GenerationStep.Feature, RegistryKey)} for built-in features (see {@link #addBuiltInFeature(GenerationStep.Feature, PlacedFeature)}).
|
||||
*/
|
||||
default boolean removeBuiltInFeature(GenerationStep.Feature step, PlacedFeature placedFeature) {
|
||||
return removeFeature(step, BuiltInRegistryKeys.get(placedFeature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a feature to one of this biomes generation steps, identified by the placed feature's registry key.
|
||||
*
|
||||
* @see BuiltinRegistries#PLACED_FEATURE
|
||||
*/
|
||||
void addFeature(GenerationStep.Feature step, RegistryKey<PlacedFeature> placedFeatureKey);
|
||||
|
||||
/**
|
||||
* Adds a placed feature from {@link BuiltinRegistries#PLACED_FEATURE} to this biome.
|
||||
*
|
||||
* <p>This method is intended for use with the placed features found in
|
||||
* classes such as {@link net.minecraft.world.gen.feature.OrePlacedFeatures}.
|
||||
*
|
||||
* <p><b>NOTE:</b> In case the placed feature is overridden in a data pack, the data pack's version
|
||||
* will be used.
|
||||
*/
|
||||
default void addBuiltInFeature(GenerationStep.Feature step, PlacedFeature placedFeature) {
|
||||
addFeature(step, BuiltInRegistryKeys.get(placedFeature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a configured carver to one of this biomes generation steps.
|
||||
*/
|
||||
void addCarver(GenerationStep.Carver step, RegistryKey<ConfiguredCarver<?>> carverKey);
|
||||
|
||||
/**
|
||||
* Adds a configured carver from {@link BuiltinRegistries#CONFIGURED_CARVER} to this biome.
|
||||
*
|
||||
* <p>This method is intended for use with the configured carvers found in {@link net.minecraft.world.gen.carver.ConfiguredCarvers}.
|
||||
*
|
||||
* <p><b>NOTE:</b> In case the configured carver is overridden in a data pack, the data pack's version
|
||||
* will be used.
|
||||
*/
|
||||
default void addBuiltInCarver(GenerationStep.Carver step, ConfiguredCarver<?> configuredCarver) {
|
||||
addCarver(step, BuiltInRegistryKeys.get(configuredCarver));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all carvers with the given key from one of this biomes generation steps.
|
||||
*
|
||||
|
@ -371,20 +327,6 @@ public interface BiomeModificationContext {
|
|||
|
||||
return anyFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #removeCarver(RegistryKey)} for built-in carvers (see {@link #addBuiltInCarver(GenerationStep.Carver, ConfiguredCarver)}).
|
||||
*/
|
||||
default boolean removeBuiltInCarver(ConfiguredCarver<?> configuredCarver) {
|
||||
return removeCarver(BuiltInRegistryKeys.get(configuredCarver));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link #removeCarver(GenerationStep.Carver, RegistryKey)} for built-in carvers (see {@link #addBuiltInCarver(GenerationStep.Carver, ConfiguredCarver)}).
|
||||
*/
|
||||
default boolean removeBuiltInCarver(GenerationStep.Carver step, ConfiguredCarver<?> configuredCarver) {
|
||||
return removeCarver(step, BuiltInRegistryKeys.get(configuredCarver));
|
||||
}
|
||||
}
|
||||
|
||||
interface SpawnSettingsContext {
|
||||
|
|
|
@ -29,8 +29,6 @@ import net.minecraft.world.gen.feature.ConfiguredFeature;
|
|||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.structure.Structure;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
/**
|
||||
* Context given to a biome selector for deciding whether it applies to a biome or not.
|
||||
*/
|
||||
|
@ -44,29 +42,6 @@ public interface BiomeSelectionContext {
|
|||
|
||||
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}.
|
||||
*
|
||||
* <p>This method is intended for use with the Vanilla configured features found in
|
||||
* classes such as {@link net.minecraft.world.gen.feature.OreConfiguredFeatures}.
|
||||
*/
|
||||
default boolean hasBuiltInFeature(ConfiguredFeature<?, ?> configuredFeature) {
|
||||
RegistryKey<ConfiguredFeature<?, ?>> key = BuiltInRegistryKeys.get(configuredFeature);
|
||||
return hasFeature(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this biome has the given placed feature, which must be registered
|
||||
* in the {@link net.minecraft.util.registry.BuiltinRegistries}.
|
||||
*
|
||||
* <p>This method is intended for use with the Vanilla placed features found in
|
||||
* classes such as {@link net.minecraft.world.gen.feature.OrePlacedFeatures}.
|
||||
*/
|
||||
default boolean hasBuiltInPlacedFeature(PlacedFeature placedFeature) {
|
||||
return hasPlacedFeature(BuiltInRegistryKeys.get(placedFeature));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this biome contains a placed feature referencing a configured feature with the given key.
|
||||
*/
|
||||
|
@ -115,17 +90,6 @@ public interface BiomeSelectionContext {
|
|||
*/
|
||||
Optional<RegistryKey<PlacedFeature>> getPlacedFeatureKey(PlacedFeature placedFeature);
|
||||
|
||||
/**
|
||||
* Returns true if the given built-in configured structure from {@link net.minecraft.util.registry.BuiltinRegistries}
|
||||
* can start in this biome in any of the chunk generators used by the current world-save.
|
||||
*
|
||||
* <p>This method is intended for use with the Vanilla configured structures found in {@link net.minecraft.world.gen.structure.Structures}.
|
||||
*/
|
||||
default boolean validForBuiltInStructure(Structure structureFeature) {
|
||||
RegistryKey<Structure> key = BuiltInRegistryKeys.get(structureFeature);
|
||||
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.
|
||||
|
|
|
@ -25,12 +25,13 @@ import com.google.common.collect.ImmutableSet;
|
|||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.dimension.DimensionOptions;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
/**
|
||||
* Provides several convenient biome selectors that can be used with {@link BiomeModifications}.
|
||||
*
|
||||
|
@ -47,21 +48,14 @@ public final class BiomeSelectors {
|
|||
return context -> true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches Biomes that have not been originally defined in a data pack, but that are defined in code.
|
||||
*/
|
||||
public static Predicate<BiomeSelectionContext> builtIn() {
|
||||
return context -> BuiltinRegistries.BIOME.containsId(context.getBiomeKey().getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a biome selector that will match all biomes from the minecraft namespace.
|
||||
*/
|
||||
public static Predicate<BiomeSelectionContext> vanilla() {
|
||||
return context -> {
|
||||
// In addition to the namespace, we also check that it doesn't come from a data pack.
|
||||
// In addition to the namespace, we also check that it exists in the vanilla registries
|
||||
return context.getBiomeKey().getValue().getNamespace().equals("minecraft")
|
||||
&& BuiltinRegistries.BIOME.containsId(context.getBiomeKey().getValue());
|
||||
&& BuiltInRegistryKeys.isBuiltinBiome(context.getBiomeKey());
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -22,4 +22,6 @@ public interface MultiNoiseSamplerHooks {
|
|||
PerlinNoiseSampler fabric_getEndBiomesSampler();
|
||||
|
||||
void fabric_setSeed(long seed);
|
||||
|
||||
long fabric_getSeed();
|
||||
}
|
||||
|
|
|
@ -29,8 +29,7 @@ import com.mojang.logging.LogUtils;
|
|||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -38,6 +37,8 @@ import net.minecraft.world.biome.source.BiomeSource;
|
|||
import net.minecraft.world.biome.source.MultiNoiseBiomeSource;
|
||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||
|
||||
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
|
||||
|
||||
/**
|
||||
* Internal data for modding Vanilla's {@link MultiNoiseBiomeSource.Preset#NETHER}.
|
||||
*/
|
||||
|
@ -67,10 +68,10 @@ public final class NetherBiomeData {
|
|||
|
||||
public static boolean canGenerateInNether(RegistryKey<Biome> biome) {
|
||||
if (NETHER_BIOMES.isEmpty()) {
|
||||
MultiNoiseBiomeSource source = MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(BuiltinRegistries.BIOME);
|
||||
MultiNoiseBiomeSource source = MultiNoiseBiomeSource.Preset.NETHER.getBiomeSource(BuiltInRegistryKeys.biomeRegistryWrapper());
|
||||
|
||||
for (RegistryEntry<Biome> entry : source.getBiomes()) {
|
||||
BuiltinRegistries.BIOME.getKey(entry.value()).ifPresent(NETHER_BIOMES::add);
|
||||
entry.getKey().ifPresent(NETHER_BIOMES::add);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,7 +82,7 @@ public final class NetherBiomeData {
|
|||
NETHER_BIOMES.clear(); // Clear cached biome source data
|
||||
}
|
||||
|
||||
private static MultiNoiseUtil.Entries<RegistryEntry<Biome>> withModdedBiomeEntries(MultiNoiseUtil.Entries<RegistryEntry<Biome>> entries, Registry<Biome> biomeRegistry) {
|
||||
private static MultiNoiseUtil.Entries<RegistryEntry<Biome>> withModdedBiomeEntries(MultiNoiseUtil.Entries<RegistryEntry<Biome>> entries, RegistryEntryLookup<Biome> biomes) {
|
||||
if (NETHER_BIOME_NOISE_POINTS.isEmpty()) {
|
||||
return entries;
|
||||
}
|
||||
|
@ -89,8 +90,10 @@ public final class NetherBiomeData {
|
|||
ArrayList<Pair<MultiNoiseUtil.NoiseHypercube, RegistryEntry<Biome>>> entryList = new ArrayList<>(entries.getEntries());
|
||||
|
||||
for (Map.Entry<RegistryKey<Biome>, MultiNoiseUtil.NoiseHypercube> entry : NETHER_BIOME_NOISE_POINTS.entrySet()) {
|
||||
if (biomeRegistry.contains(entry.getKey())) {
|
||||
entryList.add(Pair.of(entry.getValue(), biomeRegistry.entryOf(entry.getKey())));
|
||||
RegistryEntry.Reference<Biome> biomeEntry = biomes.getOptional(entry.getKey()).orElse(null);
|
||||
|
||||
if (biomeEntry != null) {
|
||||
entryList.add(Pair.of(entry.getValue(), biomeEntry));
|
||||
} else {
|
||||
LOGGER.warn("Nether biome {} not loaded", entry.getKey().getValue());
|
||||
}
|
||||
|
@ -99,7 +102,7 @@ public final class NetherBiomeData {
|
|||
return new MultiNoiseUtil.Entries<>(entryList);
|
||||
}
|
||||
|
||||
public static void modifyBiomeSource(Registry<Biome> biomeRegistry, BiomeSource biomeSource) {
|
||||
public static void modifyBiomeSource(RegistryEntryLookup<Biome> biomeRegistry, BiomeSource biomeSource) {
|
||||
if (biomeSource instanceof MultiNoiseBiomeSource multiNoiseBiomeSource) {
|
||||
if (((BiomeSourceAccess) multiNoiseBiomeSource).fabric_shouldModifyBiomeEntries() && multiNoiseBiomeSource.matchesInstance(MultiNoiseBiomeSource.Preset.NETHER)) {
|
||||
multiNoiseBiomeSource.biomeEntries = NetherBiomeData.withModdedBiomeEntries(
|
||||
|
|
|
@ -29,8 +29,8 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
|
|||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.math.noise.PerlinNoiseSampler;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -43,6 +43,7 @@ import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
|||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class TheEndBiomeData {
|
||||
public static final ThreadLocal<RegistryEntryLookup<Biome>> biomeRegistry = new ThreadLocal<>();
|
||||
public static final Set<RegistryKey<Biome>> ADDED_BIOMES = new HashSet<>();
|
||||
private static final Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> END_BIOMES_MAP = new IdentityHashMap<>();
|
||||
private static final Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> END_MIDLANDS_MAP = new IdentityHashMap<>();
|
||||
|
@ -89,8 +90,8 @@ public final class TheEndBiomeData {
|
|||
ADDED_BIOMES.add(barrens);
|
||||
}
|
||||
|
||||
public static Overrides createOverrides(Registry<Biome> biomeRegistry) {
|
||||
return new Overrides(biomeRegistry);
|
||||
public static Overrides createOverrides(RegistryEntryLookup<Biome> biomes) {
|
||||
return new Overrides(biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -112,12 +113,12 @@ public final class TheEndBiomeData {
|
|||
// cache for our own sampler (used for random biome replacement selection)
|
||||
private final Map<MultiNoiseUtil.MultiNoiseSampler, PerlinNoiseSampler> samplers = new WeakHashMap<>();
|
||||
|
||||
public Overrides(Registry<Biome> biomeRegistry) {
|
||||
this.customBiomes = ADDED_BIOMES.stream().map(biomeRegistry::entryOf).collect(Collectors.toSet());
|
||||
public Overrides(RegistryEntryLookup<Biome> biomeRegistry) {
|
||||
this.customBiomes = ADDED_BIOMES.stream().map(biomeRegistry::getOrThrow).collect(Collectors.toSet());
|
||||
|
||||
this.endMidlands = biomeRegistry.entryOf(BiomeKeys.END_MIDLANDS);
|
||||
this.endBarrens = biomeRegistry.entryOf(BiomeKeys.END_BARRENS);
|
||||
this.endHighlands = biomeRegistry.entryOf(BiomeKeys.END_HIGHLANDS);
|
||||
this.endMidlands = biomeRegistry.getOrThrow(BiomeKeys.END_MIDLANDS);
|
||||
this.endBarrens = biomeRegistry.getOrThrow(BiomeKeys.END_BARRENS);
|
||||
this.endHighlands = biomeRegistry.getOrThrow(BiomeKeys.END_HIGHLANDS);
|
||||
|
||||
this.endBiomesMap = resolveOverrides(biomeRegistry, END_BIOMES_MAP, BiomeKeys.THE_END);
|
||||
this.endMidlandsMap = resolveOverrides(biomeRegistry, END_MIDLANDS_MAP, BiomeKeys.END_MIDLANDS);
|
||||
|
@ -125,7 +126,7 @@ public final class TheEndBiomeData {
|
|||
}
|
||||
|
||||
// Resolves all RegistryKey instances to RegistryEntries
|
||||
private @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(Registry<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides, RegistryKey<Biome> vanillaKey) {
|
||||
private @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(RegistryEntryLookup<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides, RegistryKey<Biome> vanillaKey) {
|
||||
Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> result = new Object2ObjectOpenCustomHashMap<>(overrides.size(), RegistryKeyHashStrategy.INSTANCE);
|
||||
|
||||
for (Map.Entry<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> entry : overrides.entrySet()) {
|
||||
|
@ -133,7 +134,7 @@ public final class TheEndBiomeData {
|
|||
int count = picker.getEntryCount();
|
||||
if (count == 0 || (count == 1 && entry.getKey() == vanillaKey)) continue; // don't use no-op entries, for vanilla key biome check 1 as we have default entry
|
||||
|
||||
result.put(biomeRegistry.entryOf(entry.getKey()), picker.map(biomeRegistry::entryOf));
|
||||
result.put(biomeRegistry.getOrThrow(entry.getKey()), picker.map(biomeRegistry::getOrThrow));
|
||||
}
|
||||
|
||||
return result.isEmpty() ? null : result;
|
||||
|
|
|
@ -40,7 +40,6 @@ import net.minecraft.sound.BiomeMoodSound;
|
|||
import net.minecraft.sound.MusicSound;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.collection.Pool;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
|
@ -329,18 +328,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
|
|||
RegistryEntry.Reference<T> entry = registry.getEntry(key).orElse(null);
|
||||
|
||||
if (entry == null) {
|
||||
// Entry is missing. Check if it exists in the built-in registries and warn modders
|
||||
// about the worldgen changing to JSON-only.
|
||||
DynamicRegistryManager.Immutable builtInAccess = BuiltinRegistries.createBuiltinRegistryManager();
|
||||
Registry<T> builtInRegistry = builtInAccess.get(registry.getKey());
|
||||
|
||||
if (builtInRegistry.contains(key)) {
|
||||
throw new IllegalArgumentException("Entry " + key + " only exists in the built-in registry "
|
||||
+ "but a corresponding JSON file couldn't be found in the loaded data packs. "
|
||||
+ "Since 1.19.3+, the built-in registry for world generation objects is only used for data generation purposes.");
|
||||
}
|
||||
|
||||
// The key doesn't exist in either built-in registries or data packs
|
||||
// The key doesn't exist in the data packs
|
||||
throw new IllegalArgumentException("Couldn't find registry entry for " + key);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,38 +19,27 @@ package net.fabricmc.fabric.impl.biome.modification;
|
|||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.structure.Structure;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
||||
/**
|
||||
* Utility class for getting the registry keys of built-in worldgen objects and throwing proper exceptions if they
|
||||
* are not registered.
|
||||
* Utility class for accessing the worldgen data that vanilla uses to generate its vanilla datapack.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class BuiltInRegistryKeys {
|
||||
private static final RegistryWrapper.WrapperLookup vanillaRegistries = BuiltinRegistries.createWrapperLookup();
|
||||
|
||||
private BuiltInRegistryKeys() {
|
||||
}
|
||||
|
||||
public static RegistryKey<Structure> get(Structure structureFeature) {
|
||||
return BuiltinRegistries.STRUCTURE.getKey(structureFeature)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given structure is not built-in: " + structureFeature));
|
||||
public static boolean isBuiltinBiome(RegistryKey<Biome> key) {
|
||||
return biomeRegistryWrapper().getOptional(key).isPresent();
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredFeature<?, ?>> get(ConfiguredFeature<?, ?> configuredFeature) {
|
||||
return BuiltinRegistries.CONFIGURED_FEATURE.getKey(configuredFeature)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given configured feature is not built-in: " + configuredFeature));
|
||||
}
|
||||
|
||||
public static RegistryKey<PlacedFeature> get(PlacedFeature placedFeature) {
|
||||
return BuiltinRegistries.PLACED_FEATURE.getKey(placedFeature)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given placed feature is not built-in: " + placedFeature));
|
||||
}
|
||||
|
||||
public static RegistryKey<ConfiguredCarver<?>> get(ConfiguredCarver<?> configuredCarver) {
|
||||
return BuiltinRegistries.CONFIGURED_CARVER.getKey(configuredCarver)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Given configured carver is not built-in: " + configuredCarver));
|
||||
public static RegistryEntryLookup<Biome> biomeRegistryWrapper() {
|
||||
return vanillaRegistries.getWrapperOrThrow(Registry.BIOME_KEY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class ChunkNoiseSamplerMixin {
|
|||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void init(int horizontalSize, NoiseConfig noiseConfig, int i, int j, GenerationShapeConfig generationShapeConfig, DensityFunctionTypes.Beardifying arg, ChunkGeneratorSettings chunkGeneratorSettings, AquiferSampler.FluidLevelSampler fluidLevelSampler, Blender blender, CallbackInfo ci) {
|
||||
seed = noiseConfig.getLegacyWorldSeed();
|
||||
seed = ((MultiNoiseSamplerHooks) (Object) noiseConfig.getMultiNoiseSampler()).fabric_getSeed();
|
||||
}
|
||||
|
||||
@Inject(method = "createMultiNoiseSampler", at = @At("RETURN"))
|
||||
|
|
|
@ -44,6 +44,6 @@ public class MinecraftServerMixin {
|
|||
// please blame Mojang for using dynamic registry
|
||||
Registry<DimensionOptions> registry = getRegistryManager().get(Registry.DIMENSION_KEY);
|
||||
|
||||
registry.stream().forEach(dimensionOptions -> NetherBiomeData.modifyBiomeSource(getRegistryManager().get(Registry.BIOME_KEY), dimensionOptions.chunkGenerator().getBiomeSource()));
|
||||
registry.stream().forEach(dimensionOptions -> NetherBiomeData.modifyBiomeSource(getRegistryManager().getWrapperOrThrow(Registry.BIOME_KEY), dimensionOptions.chunkGenerator().getBiomeSource()));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ public class MultiNoiseUtilMultiNoiseSamplerMixin implements MultiNoiseSamplerHo
|
|||
this.seed = seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long fabric_getSeed() {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PerlinNoiseSampler fabric_getEndBiomesSampler() {
|
||||
if (endBiomesSampler == null) {
|
||||
|
|
|
@ -23,7 +23,8 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.math.noise.DoublePerlinNoiseSampler;
|
||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||
import net.minecraft.world.gen.chunk.ChunkGeneratorSettings;
|
||||
import net.minecraft.world.gen.noise.NoiseConfig;
|
||||
|
@ -37,7 +38,7 @@ public class NoiseConfigMixin {
|
|||
private MultiNoiseUtil.MultiNoiseSampler multiNoiseSampler;
|
||||
|
||||
@Inject(method = "<init>", at = @At("TAIL"))
|
||||
private void init(ChunkGeneratorSettings chunkGeneratorSettings, Registry<?> noiseRegistry, long seed, CallbackInfo ci) {
|
||||
private void init(ChunkGeneratorSettings chunkGeneratorSettings, RegistryEntryLookup<DoublePerlinNoiseSampler.NoiseParameters> arg, long seed, CallbackInfo ci) {
|
||||
((MultiNoiseSamplerHooks) (Object) multiNoiseSampler).fabric_setSeed(seed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,20 @@ import java.util.Set;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -37,15 +44,59 @@ import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
|
|||
|
||||
@Mixin(TheEndBiomeSource.class)
|
||||
public class TheEndBiomeSourceMixin extends BiomeSourceMixin {
|
||||
@Shadow
|
||||
@Mutable
|
||||
@Final
|
||||
static Codec<TheEndBiomeSource> CODEC;
|
||||
|
||||
@Unique
|
||||
private Supplier<TheEndBiomeData.Overrides> overrides;
|
||||
|
||||
@Unique
|
||||
private boolean biomeSetModified = false;
|
||||
|
||||
/**
|
||||
* Modifies the codec, so it calls the static factory method that gives us access to the
|
||||
* full biome registry instead of just the pre-defined biomes that vanilla uses.
|
||||
*/
|
||||
@Inject(method = "<clinit>", at = @At("TAIL"))
|
||||
private static void modifyCodec(CallbackInfo ci) {
|
||||
CODEC = RecordCodecBuilder.create((instance) -> {
|
||||
return instance.group(RegistryOps.getEntryLookupCodec(Registry.BIOME_KEY)).apply(instance, instance.stable(TheEndBiomeSource::method_46680));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures the biome registry at the beginning of the static factory method to allow access to it in the
|
||||
* constructor.
|
||||
*/
|
||||
@Inject(method = "method_46680", at = @At("HEAD"))
|
||||
private static void rememberLookup(RegistryEntryLookup<Biome> biomes, CallbackInfoReturnable<?> ci) {
|
||||
TheEndBiomeData.biomeRegistry.set(biomes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees up the captured biome registry.
|
||||
*/
|
||||
@Inject(method = "method_46680", at = @At("TAIL"))
|
||||
private static void clearLookup(RegistryEntryLookup<Biome> biomes, CallbackInfoReturnable<?> ci) {
|
||||
TheEndBiomeData.biomeRegistry.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the captured biome registry to set up the modded end biomes.
|
||||
*/
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void init(Registry<Biome> biomeRegistry, CallbackInfo ci) {
|
||||
overrides = Suppliers.memoize(() -> TheEndBiomeData.createOverrides(biomeRegistry));
|
||||
private void init(RegistryEntry<Biome> centerBiome, RegistryEntry<Biome> highlandsBiome, RegistryEntry<Biome> midlandsBiome, RegistryEntry<Biome> smallIslandsBiome, RegistryEntry<Biome> barrensBiome, CallbackInfo ci) {
|
||||
RegistryEntryLookup<Biome> biomes = TheEndBiomeData.biomeRegistry.get();
|
||||
|
||||
if (biomes == null) {
|
||||
throw new IllegalStateException("Biome registry not set by Mixin");
|
||||
}
|
||||
|
||||
overrides = Suppliers.memoize(() -> {
|
||||
return TheEndBiomeData.createOverrides(biomes);
|
||||
});
|
||||
}
|
||||
|
||||
@Inject(method = "getBiome", at = @At("RETURN"), cancellable = true)
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
package net.fabricmc.fabric.test.biome;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBuiltinRegistriesProvider;
|
||||
|
||||
public class DataGeneratorEntrypoint implements net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint {
|
||||
@Override
|
||||
public void onInitializeDataGenerator(FabricDataGenerator dataGenerator) {
|
||||
FabricDataGenerator.Pack pack = dataGenerator.createPack();
|
||||
pack.addProvider(FabricBuiltinRegistriesProvider.forCurrentMod());
|
||||
pack.addProvider(WorldgenProvider::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,33 +16,16 @@
|
|||
|
||||
package net.fabricmc.fabric.test.biome;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.sound.BiomeMoodSound;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
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.biome.BiomeEffects;
|
||||
import net.minecraft.world.biome.BiomeKeys;
|
||||
import net.minecraft.world.biome.GenerationSettings;
|
||||
import net.minecraft.world.biome.OverworldBiomeCreator;
|
||||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.biome.TheNetherBiomeCreator;
|
||||
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.EndPlacedFeatures;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeatures;
|
||||
import net.minecraft.world.gen.placementmodifier.BiomePlacementModifier;
|
||||
import net.minecraft.world.gen.placementmodifier.SquarePlacementModifier;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.biome.v1.BiomeModifications;
|
||||
|
@ -64,24 +47,26 @@ import net.fabricmc.fabric.api.biome.v1.TheEndBiomes;
|
|||
public class FabricBiomeTest implements ModInitializer {
|
||||
public static final String MOD_ID = "fabric-biome-api-v1-testmod";
|
||||
|
||||
private static final RegistryKey<Biome> TEST_CRIMSON_FOREST = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_crimson_forest"));
|
||||
private static final RegistryKey<Biome> CUSTOM_PLAINS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "custom_plains"));
|
||||
private static final RegistryKey<Biome> TEST_END_HIGHLANDS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_highlands"));
|
||||
private static final RegistryKey<Biome> TEST_END_MIDLANDS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_midlands"));
|
||||
private static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_barrens"));
|
||||
public static final RegistryKey<Biome> TEST_CRIMSON_FOREST = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_crimson_forest"));
|
||||
public static final RegistryKey<Biome> CUSTOM_PLAINS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "custom_plains"));
|
||||
public static final RegistryKey<Biome> TEST_END_HIGHLANDS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_highlands"));
|
||||
public static final RegistryKey<Biome> TEST_END_MIDLANDS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_midlands"));
|
||||
public static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_barrens"));
|
||||
|
||||
public static final RegistryKey<ConfiguredFeature<?, ?>> COMMON_DESERT_WELL = RegistryKey.of(
|
||||
Registry.CONFIGURED_FEATURE_KEY,
|
||||
new Identifier(FabricBiomeTest.MOD_ID, "fab_desert_well")
|
||||
);
|
||||
public static final RegistryKey<PlacedFeature> PLACED_COMMON_DESERT_WELL = RegistryKey.of(
|
||||
Registry.PLACED_FEATURE_KEY,
|
||||
new Identifier(FabricBiomeTest.MOD_ID, "fab_desert_well")
|
||||
);
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_CRIMSON_FOREST.getValue(), TheNetherBiomeCreator.createCrimsonForest());
|
||||
|
||||
NetherBiomes.addNetherBiome(BiomeKeys.PLAINS, MultiNoiseUtil.createNoiseHypercube(0.0F, 0.5F, 0.0F, 0.0F, 0.0f, 0, 0.1F));
|
||||
NetherBiomes.addNetherBiome(TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseHypercube(0.0F, -0.15F, 0.0f, 0.0F, 0.0f, 0.0F, 0.2F));
|
||||
|
||||
BuiltinRegistries.add(BuiltinRegistries.BIOME, CUSTOM_PLAINS.getValue(), OverworldBiomeCreator.createPlains(false, false, false));
|
||||
|
||||
BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_HIGHLANDS.getValue(), createEndHighlands());
|
||||
BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands());
|
||||
BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_BARRRENS.getValue(), createEndBarrens());
|
||||
|
||||
// TESTING HINT: to get to the end:
|
||||
// /execute in minecraft:the_end run tp @s 0 90 0
|
||||
TheEndBiomes.addHighlandsBiome(BiomeKeys.PLAINS, 5.0);
|
||||
|
@ -89,14 +74,6 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
TheEndBiomes.addMidlandsBiome(TEST_END_HIGHLANDS, TEST_END_MIDLANDS, 10.0);
|
||||
TheEndBiomes.addBarrensBiome(TEST_END_HIGHLANDS, TEST_END_BARRRENS, 10.0);
|
||||
|
||||
ConfiguredFeature<?, ?> COMMON_DESERT_WELL = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE);
|
||||
BuiltinRegistries.add(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(MOD_ID, "fab_desert_well"), COMMON_DESERT_WELL);
|
||||
RegistryEntry<ConfiguredFeature<?, ?>> featureEntry = BuiltinRegistries.CONFIGURED_FEATURE.getOrCreateEntry(BuiltinRegistries.CONFIGURED_FEATURE.getKey(COMMON_DESERT_WELL).orElseThrow());
|
||||
|
||||
// The placement config is taken from the vanilla desert well, but no randomness
|
||||
PlacedFeature PLACED_COMMON_DESERT_WELL = new PlacedFeature(featureEntry, List.of(SquarePlacementModifier.of(), PlacedFeatures.MOTION_BLOCKING_HEIGHTMAP, BiomePlacementModifier.of()));
|
||||
BuiltinRegistries.add(BuiltinRegistries.PLACED_FEATURE, new Identifier(MOD_ID, "fab_desert_well"), PLACED_COMMON_DESERT_WELL);
|
||||
|
||||
BiomeModifications.create(new Identifier("fabric:test_mod"))
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
BiomeSelectors.foundInOverworld(),
|
||||
|
@ -105,7 +82,7 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
BiomeSelectors.includeByKey(BiomeKeys.DESERT), // TODO: switch to fabric desert biome tag once it is there?
|
||||
context -> {
|
||||
context.getGenerationSettings().addFeature(GenerationStep.Feature.TOP_LAYER_MODIFICATION,
|
||||
BuiltinRegistries.PLACED_FEATURE.getKey(PLACED_COMMON_DESERT_WELL).orElseThrow()
|
||||
PLACED_COMMON_DESERT_WELL
|
||||
);
|
||||
})
|
||||
.add(ModificationPhase.ADDITIONS,
|
||||
|
@ -130,27 +107,4 @@ public class FabricBiomeTest implements ModInitializer {
|
|||
10.0
|
||||
);
|
||||
}
|
||||
|
||||
// These are used for testing the spacing of custom end biomes.
|
||||
private static Biome createEndHighlands() {
|
||||
GenerationSettings.Builder builder = new GenerationSettings.Builder()
|
||||
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, EndPlacedFeatures.END_GATEWAY_RETURN);
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndMidlands() {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndBarrens() {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder());
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
|
||||
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
|
||||
DefaultBiomeFeatures.addPlainsMobs(builder2);
|
||||
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.build()).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.test.biome;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.sound.BiomeMoodSound;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeEffects;
|
||||
import net.minecraft.world.biome.GenerationSettings;
|
||||
import net.minecraft.world.biome.OverworldBiomeCreator;
|
||||
import net.minecraft.world.biome.SpawnSettings;
|
||||
import net.minecraft.world.biome.TheNetherBiomeCreator;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.EndPlacedFeatures;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
import net.minecraft.world.gen.feature.PlacedFeatures;
|
||||
import net.minecraft.world.gen.placementmodifier.BiomePlacementModifier;
|
||||
import net.minecraft.world.gen.placementmodifier.SquarePlacementModifier;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricWorldgenProvider;
|
||||
|
||||
public class WorldgenProvider extends FabricWorldgenProvider {
|
||||
public WorldgenProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries, Entries entries) {
|
||||
entries.add(FabricBiomeTest.TEST_CRIMSON_FOREST, TheNetherBiomeCreator.createCrimsonForest(entries.placedFeatures(), entries.configuredCarvers()));
|
||||
entries.add(FabricBiomeTest.CUSTOM_PLAINS, OverworldBiomeCreator.createPlains(entries.placedFeatures(), entries.configuredCarvers(), false, false, false));
|
||||
entries.add(FabricBiomeTest.TEST_END_HIGHLANDS, createEndHighlands(entries));
|
||||
;
|
||||
entries.add(FabricBiomeTest.TEST_END_MIDLANDS, createEndMidlands(entries));
|
||||
entries.add(FabricBiomeTest.TEST_END_BARRRENS, createEndBarrens(entries));
|
||||
|
||||
ConfiguredFeature<?, ?> COMMON_DESERT_WELL = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE);
|
||||
|
||||
RegistryEntry<ConfiguredFeature<?, ?>> featureRef = entries.add(FabricBiomeTest.COMMON_DESERT_WELL, COMMON_DESERT_WELL);
|
||||
|
||||
// The placement config is taken from the vanilla desert well, but no randomness
|
||||
PlacedFeature PLACED_COMMON_DESERT_WELL = new PlacedFeature(featureRef, List.of(SquarePlacementModifier.of(), PlacedFeatures.MOTION_BLOCKING_HEIGHTMAP, BiomePlacementModifier.of()));
|
||||
entries.add(FabricBiomeTest.PLACED_COMMON_DESERT_WELL, PLACED_COMMON_DESERT_WELL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Fabric Biome Testmod";
|
||||
}
|
||||
|
||||
// These are used for testing the spacing of custom end biomes.
|
||||
private static Biome createEndHighlands(Entries entries) {
|
||||
GenerationSettings.Builder builder = new GenerationSettings.Builder(entries.placedFeatures(), entries.configuredCarvers())
|
||||
.feature(GenerationStep.Feature.SURFACE_STRUCTURES, EndPlacedFeatures.END_GATEWAY_RETURN);
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndMidlands(Entries entries) {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder(entries.placedFeatures(), entries.configuredCarvers()));
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
public static Biome createEndBarrens(Entries entries) {
|
||||
GenerationSettings.Builder builder = (new GenerationSettings.Builder(entries.placedFeatures(), entries.configuredCarvers()));
|
||||
return composeEndSpawnSettings(builder);
|
||||
}
|
||||
|
||||
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
|
||||
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
|
||||
DefaultBiomeFeatures.addPlainsMobs(builder2);
|
||||
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).temperature(0.5F).downfall(0.5F).effects((new BiomeEffects.Builder()).waterColor(4159204).waterFogColor(329011).fogColor(10518688).skyColor(0).moodSound(BiomeMoodSound.CAVE).build()).spawnSettings(builder2.build()).generationSettings(builder.method_46671()).build();
|
||||
}
|
||||
}
|
|
@ -58,7 +58,7 @@ abstract class ClientPlayNetworkHandlerMixin {
|
|||
private void onGameJoin(GameJoinS2CPacket packet, CallbackInfo info) {
|
||||
final CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>();
|
||||
ClientCommandInternals.setActiveDispatcher(dispatcher);
|
||||
ClientCommandRegistrationCallback.EVENT.invoker().register(dispatcher, new CommandRegistryAccess(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures));
|
||||
ClientCommandRegistrationCallback.EVENT.invoker().register(dispatcher, CommandRegistryAccess.of(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures));
|
||||
ClientCommandInternals.finalizeInit();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.tag.BiomeTags;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
|
@ -25,13 +28,13 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
|||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBiomeTags;
|
||||
|
||||
public class BiomeTagGenerator extends FabricTagProvider.DynamicRegistryTagProvider<Biome> {
|
||||
public BiomeTagGenerator(FabricDataOutput output) {
|
||||
super(output, Registry.BIOME_KEY);
|
||||
public class BiomeTagGenerator extends FabricTagProvider<Biome> {
|
||||
public BiomeTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, Registry.BIOME_KEY, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup arg) {
|
||||
generateDimensionTags();
|
||||
generateCategoryTags();
|
||||
generateOtherBiomeTypes();
|
||||
|
|
|
@ -16,20 +16,25 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalBlockTags;
|
||||
|
||||
public class BlockTagGenerator extends FabricTagProvider.BlockTagProvider {
|
||||
public BlockTagGenerator(FabricDataOutput output) {
|
||||
super(output);
|
||||
public BlockTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(ConventionalBlockTags.QUARTZ_ORES)
|
||||
.add(Blocks.NETHER_QUARTZ_ORE);
|
||||
getOrCreateTagBuilder(ConventionalBlockTags.ORES)
|
||||
|
@ -52,6 +57,11 @@ public class BlockTagGenerator extends FabricTagProvider.BlockTagProvider {
|
|||
generateShulkerTag();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<Block> reverseLookup(Block block) {
|
||||
return block.getRegistryEntry().registryKey();
|
||||
}
|
||||
|
||||
private void generateShulkerTag() {
|
||||
getOrCreateTagBuilder(ConventionalBlockTags.SHULKER_BOXES)
|
||||
.add(Blocks.SHULKER_BOX)
|
||||
|
|
|
@ -16,21 +16,22 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
||||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalEnchantmentTags;
|
||||
|
||||
public class EnchantmentTagGenerator extends FabricTagProvider<Enchantment> {
|
||||
public EnchantmentTagGenerator(FabricDataOutput output) {
|
||||
super(output, Registry.ENCHANTMENT);
|
||||
public class EnchantmentTagGenerator extends FabricTagProvider.EnchantmentTagProvider {
|
||||
public EnchantmentTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(ConventionalEnchantmentTags.INCREASES_BLOCK_DROPS)
|
||||
.add(Enchantments.FORTUNE);
|
||||
getOrCreateTagBuilder(ConventionalEnchantmentTags.INCREASES_ENTITY_DROPS)
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.entity.EntityType;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
|
@ -23,12 +26,12 @@ import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
|||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalEntityTypeTags;
|
||||
|
||||
public class EntityTypeTagGenerator extends FabricTagProvider.EntityTypeTagProvider {
|
||||
public EntityTypeTagGenerator(FabricDataOutput output) {
|
||||
super(output);
|
||||
public EntityTypeTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(ConventionalEntityTypeTags.BOSSES)
|
||||
.add(EntityType.ENDER_DRAGON)
|
||||
.add(EntityType.WITHER);
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.tag.FluidTags;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
|
@ -23,12 +26,12 @@ import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
|
|||
import net.fabricmc.fabric.api.tag.convention.v1.ConventionalFluidTags;
|
||||
|
||||
public class FluidTagGenerator extends FabricTagProvider.FluidTagProvider {
|
||||
public FluidTagGenerator(FabricDataOutput output) {
|
||||
super(output);
|
||||
public FluidTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(ConventionalFluidTags.WATER)
|
||||
.addOptionalTag(FluidTags.WATER);
|
||||
getOrCreateTagBuilder(ConventionalFluidTags.LAVA)
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
package net.fabricmc.fabric.impl.tag.convention.datagen.generators;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.tag.ItemTags;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
@ -57,12 +60,12 @@ public class ItemTagGenerator extends FabricTagProvider.ItemTagProvider {
|
|||
@Deprecated
|
||||
private static final Identifier FABRIC_SWORDS = createFabricId("swords");
|
||||
|
||||
public ItemTagGenerator(FabricDataOutput output) {
|
||||
super(output);
|
||||
public ItemTagGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup arg) {
|
||||
generateToolTags();
|
||||
generateBucketTags();
|
||||
generateOreAndRelatedTags();
|
||||
|
|
|
@ -18,6 +18,7 @@ package net.fabricmc.fabric.api.datagen.v1;
|
|||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
|
@ -25,6 +26,7 @@ import net.minecraft.SharedConstants;
|
|||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
|
||||
|
@ -35,13 +37,15 @@ public final class FabricDataGenerator extends DataGenerator {
|
|||
private final ModContainer modContainer;
|
||||
private final boolean strictValidation;
|
||||
private final FabricDataOutput fabricOutput;
|
||||
private final CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture;
|
||||
|
||||
@ApiStatus.Internal
|
||||
public FabricDataGenerator(Path output, ModContainer mod, boolean strictValidation) {
|
||||
public FabricDataGenerator(Path output, ModContainer mod, boolean strictValidation, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, SharedConstants.getGameVersion(), true);
|
||||
this.modContainer = Objects.requireNonNull(mod);
|
||||
this.strictValidation = strictValidation;
|
||||
this.fabricOutput = new FabricDataOutput(mod, output, strictValidation);
|
||||
this.registriesFuture = registriesFuture;
|
||||
}
|
||||
|
||||
public Pack createPack() {
|
||||
|
@ -85,7 +89,7 @@ public final class FabricDataGenerator extends DataGenerator {
|
|||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public DataGenerator.Pack createVanilla(boolean shouldRun) {
|
||||
public DataGenerator.Pack createVanillaPack(boolean shouldRun) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
@ -112,9 +116,18 @@ public final class FabricDataGenerator extends DataGenerator {
|
|||
return super.addProvider(output -> factory.create((FabricDataOutput) output));
|
||||
}
|
||||
|
||||
public <T extends DataProvider> T addProvider(RegistryDependentFactory<T> factory) {
|
||||
return super.addProvider(output -> factory.create((FabricDataOutput) output, registriesFuture));
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Factory<T extends DataProvider> {
|
||||
T create(FabricDataOutput output);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface RegistryDependentFactory<T extends DataProvider> {
|
||||
T create(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,126 +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.api.datagen.v1.provider;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Encoder;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.DataWriter;
|
||||
import net.minecraft.data.report.WorldgenProvider;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
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.util.registry.RegistryLoader;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
|
||||
/**
|
||||
* Data-generates all entries from {@link BuiltinRegistries} that matches a given filter (i.e. mod id).
|
||||
*
|
||||
* @see WorldgenProvider For Vanilla's data provider that does the same for the entire registry.
|
||||
*/
|
||||
public class FabricBuiltinRegistriesProvider implements DataProvider {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(FabricBuiltinRegistriesProvider.class);
|
||||
|
||||
private final Predicate<RegistryKey<?>> entryFilter;
|
||||
private final FabricDataOutput output;
|
||||
|
||||
private FabricBuiltinRegistriesProvider(FabricDataOutput output, Predicate<RegistryKey<?>> entryFilter) {
|
||||
this.output = output;
|
||||
this.entryFilter = entryFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A provider that will export all entries from {@link BuiltinRegistries} for the mod running the
|
||||
* data generation.
|
||||
*/
|
||||
public static FabricDataGenerator.Pack.Factory<FabricBuiltinRegistriesProvider> forCurrentMod() {
|
||||
return output -> new FabricBuiltinRegistriesProvider(
|
||||
output,
|
||||
e -> e.getValue().getNamespace().equals(output.getModId())
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(DataWriter writer) {
|
||||
DynamicRegistryManager dynamicRegistryManager = BuiltinRegistries.createBuiltinRegistryManager();
|
||||
DynamicOps<JsonElement> dynamicOps = RegistryOps.of(JsonOps.INSTANCE, dynamicRegistryManager);
|
||||
|
||||
final List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
|
||||
for (RegistryLoader.Entry<?> entry : RegistryLoader.DYNAMIC_REGISTRIES) {
|
||||
futures.add(this.writeRegistryEntries(writer, dynamicRegistryManager, dynamicOps, entry));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<?> writeRegistryEntries(DataWriter writer, DynamicRegistryManager registryManager, DynamicOps<JsonElement> ops, RegistryLoader.Entry<T> registry) {
|
||||
RegistryKey<? extends Registry<T>> registryKey = registry.key();
|
||||
Registry<T> registry2 = registryManager.get(registryKey);
|
||||
DataOutput.PathResolver pathResolver = this.output.getResolver(DataOutput.OutputType.DATA_PACK, registryKey.getValue().getPath());
|
||||
|
||||
final List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<RegistryKey<T>, T> regEntry : registry2.getEntrySet()) {
|
||||
RegistryKey<T> key = regEntry.getKey();
|
||||
|
||||
if (!entryFilter.test(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Path path = pathResolver.resolveJson(key.getValue());
|
||||
futures.add(writeToPath(path, writer, ops, registry.elementCodec(), regEntry.getValue()));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
private static <E> CompletableFuture<?> writeToPath(Path path, DataWriter cache, DynamicOps<JsonElement> json, Encoder<E> encoder, E value) {
|
||||
Optional<JsonElement> optional = encoder.encodeStart(json, value).resultOrPartial((error) -> {
|
||||
LOGGER.error("Couldn't serialize element {}: {}", path, error);
|
||||
});
|
||||
|
||||
if (optional.isPresent()) {
|
||||
return DataProvider.writeToPath(cache, optional.get(), path);
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Built-In Registry Content";
|
||||
}
|
||||
}
|
|
@ -17,12 +17,17 @@
|
|||
package net.fabricmc.fabric.api.datagen.v1.provider;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.data.server.tag.AbstractTagProvider;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.item.Item;
|
||||
|
@ -35,15 +40,13 @@ import net.minecraft.tag.TagBuilder;
|
|||
import net.minecraft.tag.TagEntry;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.RegistryLoader;
|
||||
import net.minecraft.world.event.GameEvent;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper;
|
||||
import net.fabricmc.fabric.impl.datagen.ForcedTagEntry;
|
||||
|
||||
/**
|
||||
|
@ -58,7 +61,6 @@ import net.fabricmc.fabric.impl.datagen.ForcedTagEntry;
|
|||
* @see FluidTagProvider
|
||||
* @see EntityTypeTagProvider
|
||||
* @see GameEventTagProvider
|
||||
* @see DynamicRegistryTagProvider
|
||||
*/
|
||||
public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
||||
/**
|
||||
|
@ -67,20 +69,34 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* <p>Common implementations of this class are provided. For example @see BlockTagProvider
|
||||
*
|
||||
* @param output The {@link FabricDataOutput} instance
|
||||
* @param registry The backing registry for the Tag type.
|
||||
* @param registriesFuture The backing registry for the Tag type.
|
||||
*/
|
||||
public FabricTagProvider(FabricDataOutput output, Registry<T> registry) {
|
||||
super(output, registry);
|
||||
|
||||
if (!(this instanceof DynamicRegistryTagProvider) && BuiltinRegistries.REGISTRIES.contains((RegistryKey) registry.getKey())) {
|
||||
throw new IllegalArgumentException("Using FabricTagProvider to generate dynamic registry tags is not supported, Use DynamicRegistryTagProvider instead.");
|
||||
}
|
||||
public FabricTagProvider(FabricDataOutput output, RegistryKey<? extends Registry<T>> registryKey, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registryKey, registriesFuture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this method and then use {@link FabricTagProvider#getOrCreateTagBuilder} to get and register new tag builders.
|
||||
*/
|
||||
protected abstract void generateTags();
|
||||
protected abstract void configure(RegistryWrapper.WrapperLookup arg);
|
||||
|
||||
/**
|
||||
* Override to enable adding objects to the tag builder directly.
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
protected RegistryKey<T> reverseLookup(T element) {
|
||||
Registry registry = Registry.REGISTRIES.get((RegistryKey) field_40957);
|
||||
|
||||
if (registry != null) {
|
||||
Optional<RegistryEntry<T>> key = registry.getKey(element);
|
||||
|
||||
if (key.isPresent()) {
|
||||
return (RegistryKey<T>) key.get();
|
||||
}
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Adding objects is not supported by " + getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link FabricTagBuilder} for the given {@link TagKey} tag.
|
||||
|
@ -89,21 +105,21 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @return The {@link FabricTagBuilder} instance
|
||||
*/
|
||||
@Override
|
||||
protected FabricTagBuilder<T> getOrCreateTagBuilder(TagKey<T> tag) {
|
||||
return new FabricTagBuilder<>(super.getOrCreateTagBuilder(tag));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void configure() {
|
||||
generateTags();
|
||||
protected FabricTagBuilder getOrCreateTagBuilder(TagKey<T> tag) {
|
||||
return new FabricTagBuilder(super.getOrCreateTagBuilder(tag));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class to create {@link Block} tags in the "/blocks" tag directory.
|
||||
*/
|
||||
public abstract static class BlockTagProvider extends FabricTagProvider<Block> {
|
||||
public BlockTagProvider(FabricDataOutput output) {
|
||||
super(output, Registry.BLOCK);
|
||||
public BlockTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, Registry.BLOCK_KEY, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<Block> reverseLookup(Block element) {
|
||||
return element.getRegistryEntry().registryKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,8 +135,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @param output The {@link FabricDataOutput} instance
|
||||
*/
|
||||
public ItemTagProvider(FabricDataOutput output, @Nullable FabricTagProvider.BlockTagProvider blockTagProvider) {
|
||||
super(output, Registry.ITEM);
|
||||
public ItemTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture, @Nullable FabricTagProvider.BlockTagProvider blockTagProvider) {
|
||||
super(output, Registry.ITEM_KEY, completableFuture);
|
||||
|
||||
this.blockTagBuilderProvider = blockTagProvider == null ? null : blockTagProvider::getTagBuilder;
|
||||
}
|
||||
|
@ -130,8 +146,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @param output The {@link FabricDataOutput} instance
|
||||
*/
|
||||
public ItemTagProvider(FabricDataOutput output) {
|
||||
this(output, null);
|
||||
public ItemTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
this(output, completableFuture, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,7 +155,6 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* <p>The {@link ItemTagProvider} tag provider must be constructed with an associated {@link BlockTagProvider} tag provider to use this method.
|
||||
*
|
||||
* <p>Any block ids that do not exist in the item registry will be filtered out automatically.
|
||||
*
|
||||
* @param blockTag The block tag to copy from.
|
||||
* @param itemTag The item tag to copy to.
|
||||
|
@ -147,7 +162,12 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
public void copy(TagKey<Block> blockTag, TagKey<Item> itemTag) {
|
||||
TagBuilder blockTagBuilder = Objects.requireNonNull(this.blockTagBuilderProvider, "Pass Block tag provider via constructor to use copy").apply(blockTag);
|
||||
TagBuilder itemTagBuilder = this.getTagBuilder(itemTag);
|
||||
blockTagBuilder.build().stream().filter((entry) -> entry.canAdd(this.registry::containsId, (id) -> true)).forEach(itemTagBuilder::add);
|
||||
blockTagBuilder.build().forEach(itemTagBuilder::add);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<Item> reverseLookup(Item element) {
|
||||
return element.getRegistryEntry().registryKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,8 +175,28 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* Extend this class to create {@link Fluid} tags in the "/fluids" tag directory.
|
||||
*/
|
||||
public abstract static class FluidTagProvider extends FabricTagProvider<Fluid> {
|
||||
public FluidTagProvider(FabricDataOutput output) {
|
||||
super(output, Registry.FLUID);
|
||||
public FluidTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, Registry.FLUID_KEY, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<Fluid> reverseLookup(Fluid element) {
|
||||
return element.getRegistryEntry().registryKey();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class to create {@link Enchantment} tags in the "/enchantments" tag directory.
|
||||
*/
|
||||
public abstract static class EnchantmentTagProvider extends FabricTagProvider<Enchantment> {
|
||||
public EnchantmentTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, Registry.ENCHANTMENT_KEY, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<Enchantment> reverseLookup(Enchantment element) {
|
||||
return Registry.ENCHANTMENT.getKey(element)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Enchantment " + element + " is not registered"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,8 +204,13 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* Extend this class to create {@link EntityType} tags in the "/entity_types" tag directory.
|
||||
*/
|
||||
public abstract static class EntityTypeTagProvider extends FabricTagProvider<EntityType<?>> {
|
||||
public EntityTypeTagProvider(FabricDataOutput output) {
|
||||
super(output, Registry.ENTITY_TYPE);
|
||||
public EntityTypeTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, Registry.ENTITY_TYPE_KEY, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<EntityType<?>> reverseLookup(EntityType<?> element) {
|
||||
return element.getRegistryEntry().registryKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,39 +218,24 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* Extend this class to create {@link GameEvent} tags in the "/game_events" tag directory.
|
||||
*/
|
||||
public abstract static class GameEventTagProvider extends FabricTagProvider<GameEvent> {
|
||||
public GameEventTagProvider(FabricDataOutput output) {
|
||||
super(output, Registry.GAME_EVENT);
|
||||
public GameEventTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> completableFuture) {
|
||||
super(output, Registry.GAME_EVENT_KEY, completableFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RegistryKey<GameEvent> reverseLookup(GameEvent element) {
|
||||
return element.getRegistryEntry().registryKey();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend this class to create dynamic registry tags.
|
||||
* An extension to {@link ObjectBuilder} that provides additional functionality.
|
||||
*/
|
||||
public abstract static class DynamicRegistryTagProvider<T> extends FabricTagProvider<T> {
|
||||
/**
|
||||
* Construct a new {@link DynamicRegistryTagProvider}.
|
||||
*
|
||||
* @param output The {@link FabricDataOutput} instance
|
||||
* @param registryKey The registry key of the dynamic registry
|
||||
* @throws IllegalArgumentException if the registry is static registry
|
||||
*/
|
||||
protected DynamicRegistryTagProvider(FabricDataOutput output, RegistryKey<? extends Registry<T>> registryKey) {
|
||||
super(output, FabricDataGenHelper.getFakeDynamicRegistry(registryKey));
|
||||
if (RegistryLoader.DYNAMIC_REGISTRIES.stream().noneMatch(o -> o.key() == registryKey)
|
||||
&& RegistryLoader.DIMENSION_REGISTRIES.stream().noneMatch(o -> o.key() == registryKey)) {
|
||||
throw new IllegalArgumentException("Only dynamic registries are supported in this tag provider.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension to {@link net.minecraft.data.server.AbstractTagProvider.ObjectBuilder} that provides additional functionality.
|
||||
*/
|
||||
public final class FabricTagBuilder<T> extends ObjectBuilder<T> {
|
||||
public final class FabricTagBuilder extends ObjectBuilder<T> {
|
||||
private final AbstractTagProvider.ObjectBuilder<T> parent;
|
||||
|
||||
private FabricTagBuilder(ObjectBuilder<T> parent) {
|
||||
super(parent.builder, parent.registry);
|
||||
super(parent.builder);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
@ -216,22 +246,52 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> setReplace(boolean replace) {
|
||||
public FabricTagBuilder setReplace(boolean replace) {
|
||||
((net.fabricmc.fabric.impl.datagen.FabricTagBuilder) builder).fabric_setReplace(replace);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder add(T element) {
|
||||
add(reverseLookup(element));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple elements to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
@SafeVarargs
|
||||
public final FabricTagBuilder add(T... element) {
|
||||
Stream.of(element).map(FabricTagProvider.this::reverseLookup).forEach(this::add);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
* @see #add(Identifier)
|
||||
*/
|
||||
public FabricTagBuilder add(RegistryKey<T> registryKey) {
|
||||
parent.method_46835(registryKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single element to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
* @throws UnsupportedOperationException if the provider is an instance of {@link DynamicRegistryTagProvider}
|
||||
* @see #add(Identifier)
|
||||
*/
|
||||
@Override
|
||||
public FabricTagBuilder<T> add(T element) {
|
||||
assertStaticRegistry();
|
||||
parent.add(element);
|
||||
public FabricTagBuilder method_46835(RegistryKey<T> registryKey) {
|
||||
parent.method_46835(registryKey);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -240,27 +300,18 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> add(Identifier id) {
|
||||
public FabricTagBuilder add(Identifier id) {
|
||||
builder.add(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single element to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> add(RegistryKey<? extends T> registryKey) {
|
||||
return add(registryKey.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an optional {@link Identifier} to the tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
@Override
|
||||
public FabricTagBuilder<T> addOptional(Identifier id) {
|
||||
public FabricTagBuilder addOptional(Identifier id) {
|
||||
parent.addOptional(id);
|
||||
return this;
|
||||
}
|
||||
|
@ -270,7 +321,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> addOptional(RegistryKey<? extends T> registryKey) {
|
||||
public FabricTagBuilder addOptional(RegistryKey<? extends T> registryKey) {
|
||||
return addOptional(registryKey.getValue());
|
||||
}
|
||||
|
||||
|
@ -290,7 +341,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @see ItemTags
|
||||
*/
|
||||
@Override
|
||||
public FabricTagBuilder<T> addTag(TagKey<T> tag) {
|
||||
public FabricTagBuilder addTag(TagKey<T> tag) {
|
||||
builder.addTag(tag.id());
|
||||
return this;
|
||||
}
|
||||
|
@ -301,7 +352,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
@Override
|
||||
public FabricTagBuilder<T> addOptionalTag(Identifier id) {
|
||||
public FabricTagBuilder addOptionalTag(Identifier id) {
|
||||
parent.addOptionalTag(id);
|
||||
return this;
|
||||
}
|
||||
|
@ -311,7 +362,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> addOptionalTag(TagKey<T> tag) {
|
||||
public FabricTagBuilder addOptionalTag(TagKey<T> tag) {
|
||||
return addOptionalTag(tag.id());
|
||||
}
|
||||
|
||||
|
@ -323,7 +374,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> forceAddTag(TagKey<T> tag) {
|
||||
public FabricTagBuilder forceAddTag(TagKey<T> tag) {
|
||||
builder.add(new ForcedTagEntry(TagEntry.create(tag.id())));
|
||||
return this;
|
||||
}
|
||||
|
@ -332,26 +383,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* Add multiple elements to this tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
* @throws UnsupportedOperationException if the provider is an instance of {@link DynamicRegistryTagProvider}
|
||||
*/
|
||||
@SafeVarargs
|
||||
@Override
|
||||
public final FabricTagBuilder<T> add(T... elements) {
|
||||
assertStaticRegistry();
|
||||
|
||||
for (T element : elements) {
|
||||
add(element);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add multiple elements to this tag.
|
||||
*
|
||||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
public FabricTagBuilder<T> add(Identifier... ids) {
|
||||
public FabricTagBuilder add(Identifier... ids) {
|
||||
for (Identifier id : ids) {
|
||||
add(id);
|
||||
}
|
||||
|
@ -365,18 +398,13 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
|
|||
* @return the {@link FabricTagBuilder} instance
|
||||
*/
|
||||
@SafeVarargs
|
||||
public final FabricTagBuilder<T> add(RegistryKey<T>... registryKeys) {
|
||||
for (RegistryKey<? extends T> registryKey : registryKeys) {
|
||||
@Override
|
||||
public final FabricTagBuilder add(RegistryKey<T>... registryKeys) {
|
||||
for (RegistryKey<T> registryKey : registryKeys) {
|
||||
add(registryKey);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void assertStaticRegistry() {
|
||||
if (FabricTagProvider.this instanceof DynamicRegistryTagProvider) {
|
||||
throw new UnsupportedOperationException("Adding object instances is not supported for DynamicRegistryTagProvider.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* 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.api.datagen.v1.provider;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.DynamicOps;
|
||||
import com.mojang.serialization.Encoder;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.data.DataOutput;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.data.DataWriter;
|
||||
import net.minecraft.data.report.WorldgenProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryEntry;
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.registry.RegistryEntryOwner;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.RegistryLoader;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.world.gen.carver.ConfiguredCarver;
|
||||
import net.minecraft.world.gen.feature.PlacedFeature;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
|
||||
/**
|
||||
* A provider to help with data-generation of worldgen objects.
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
public abstract class FabricWorldgenProvider implements DataProvider {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(WorldgenProvider.class);
|
||||
|
||||
private final FabricDataOutput output;
|
||||
private final CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture;
|
||||
|
||||
public FabricWorldgenProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
this.output = output;
|
||||
this.registriesFuture = registriesFuture;
|
||||
}
|
||||
|
||||
protected abstract void configure(RegistryWrapper.WrapperLookup registries, Entries entries);
|
||||
|
||||
public static final class Entries {
|
||||
private final RegistryWrapper.WrapperLookup registries;
|
||||
// Registry ID -> Entries for that registry
|
||||
private final Map<Identifier, RegistryEntries<?>> queuedEntries;
|
||||
|
||||
@ApiStatus.Internal
|
||||
Entries(RegistryWrapper.WrapperLookup registries) {
|
||||
this.registries = registries;
|
||||
this.queuedEntries = RegistryLoader.DYNAMIC_REGISTRIES.stream()
|
||||
.collect(Collectors.toMap(
|
||||
e -> e.key().getValue(),
|
||||
e -> RegistryEntries.create(registries, e)
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets access to all lookups.
|
||||
*/
|
||||
public RegistryWrapper.WrapperLookup getLookups() {
|
||||
return registries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a lookup for entries from the given registry.
|
||||
*/
|
||||
public <T> RegistryEntryLookup<T> getLookup(RegistryKey<? extends Registry<T>> registryKey) {
|
||||
return registries.getWrapperOrThrow(registryKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lookup for placed features. Useful when creating biomes.
|
||||
*/
|
||||
public RegistryEntryLookup<PlacedFeature> placedFeatures() {
|
||||
return getLookup(Registry.PLACED_FEATURE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a lookup for configured carvers features. Useful when creating biomes.
|
||||
*/
|
||||
public RegistryEntryLookup<ConfiguredCarver<?>> configuredCarvers() {
|
||||
return getLookup(Registry.CONFIGURED_CARVER_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to a registry entry for use in other registrations.
|
||||
*/
|
||||
public <T> RegistryEntry<T> ref(RegistryKey<T> key) {
|
||||
RegistryEntries<T> entries = getQueuedEntries(key);
|
||||
return RegistryEntry.Reference.standAlone(entries.lookup, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new object to be data generated and returns a reference to it for use in other worldgen objects.
|
||||
*/
|
||||
public <T> RegistryEntry<T> add(RegistryKey<T> registry, T object) {
|
||||
return getQueuedEntries(registry).add(registry.getValue(), object);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> RegistryEntries<T> getQueuedEntries(RegistryKey<T> key) {
|
||||
RegistryEntries<?> regEntries = queuedEntries.get(key.getRegistry());
|
||||
|
||||
if (regEntries == null) {
|
||||
throw new IllegalArgumentException("Registry " + key.getRegistry() + " is not loaded from datapacks");
|
||||
}
|
||||
|
||||
return (RegistryEntries<T>) regEntries;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RegistryEntries<T> {
|
||||
final RegistryEntryOwner<T> lookup;
|
||||
final RegistryKey<? extends Registry<T>> registry;
|
||||
final Codec<T> elementCodec;
|
||||
Map<RegistryKey<T>, T> entries = new IdentityHashMap<>();
|
||||
|
||||
RegistryEntries(RegistryEntryOwner<T> lookup,
|
||||
RegistryKey<? extends Registry<T>> registry,
|
||||
Codec<T> elementCodec) {
|
||||
this.lookup = lookup;
|
||||
this.registry = registry;
|
||||
this.elementCodec = elementCodec;
|
||||
}
|
||||
|
||||
static <T> RegistryEntries<T> create(RegistryWrapper.WrapperLookup lookups, RegistryLoader.Entry<T> loaderEntry) {
|
||||
RegistryWrapper.Impl<T> lookup = lookups.getWrapperOrThrow(loaderEntry.key());
|
||||
return new RegistryEntries<>(lookup, loaderEntry.key(), loaderEntry.elementCodec());
|
||||
}
|
||||
|
||||
public RegistryEntry<T> add(RegistryKey<T> key, T value) {
|
||||
if (entries.put(key, value) != null) {
|
||||
throw new IllegalArgumentException("Trying to add registry key " + key + " more than once.");
|
||||
}
|
||||
|
||||
return RegistryEntry.Reference.standAlone(lookup, key);
|
||||
}
|
||||
|
||||
public RegistryEntry<T> add(Identifier id, T value) {
|
||||
return add(RegistryKey.of(registry, id), value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<?> run(DataWriter writer) {
|
||||
return registriesFuture.thenCompose(registries -> {
|
||||
return CompletableFuture
|
||||
.supplyAsync(() -> {
|
||||
Entries entries = new Entries(registries);
|
||||
configure(registries, entries);
|
||||
return entries;
|
||||
})
|
||||
.thenCompose(entries -> {
|
||||
final RegistryOps<JsonElement> dynamicOps = RegistryOps.of(JsonOps.INSTANCE, registries);
|
||||
ArrayList<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
|
||||
for (RegistryEntries<?> registryEntries : entries.queuedEntries.values()) {
|
||||
futures.add(writeRegistryEntries(writer, dynamicOps, registryEntries));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<?> writeRegistryEntries(DataWriter writer, RegistryOps<JsonElement> ops, RegistryEntries<T> entries) {
|
||||
final RegistryKey<? extends Registry<T>> registry = entries.registry;
|
||||
final DataOutput.PathResolver pathResolver = output.getResolver(DataOutput.OutputType.DATA_PACK, registry.getValue().getPath());
|
||||
final List<CompletableFuture<?>> futures = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<RegistryKey<T>, T> entry : entries.entries.entrySet()) {
|
||||
Path path = pathResolver.resolveJson(entry.getKey().getValue());
|
||||
futures.add(writeToPath(path, writer, ops, entries.elementCodec, entry.getValue()));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new));
|
||||
}
|
||||
|
||||
private static <E> CompletableFuture<?> writeToPath(Path path, DataWriter cache, DynamicOps<JsonElement> json, Encoder<E> encoder, E value) {
|
||||
Optional<JsonElement> optional = encoder.encodeStart(json, value).resultOrPartial((error) -> {
|
||||
LOGGER.error("Couldn't serialize element {}: {}", path, error);
|
||||
});
|
||||
|
||||
if (optional.isPresent()) {
|
||||
return DataProvider.writeToPath(cache, optional.get(), path);
|
||||
}
|
||||
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
}
|
|
@ -22,24 +22,20 @@ import java.util.IdentityHashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import com.mojang.logging.LogUtils;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.minecraft.data.server.tag.AbstractTagProvider;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
|
||||
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider.DynamicRegistryTagProvider;
|
||||
import net.fabricmc.fabric.api.resource.conditions.v1.ConditionJsonProvider;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.fabricmc.loader.api.ModContainer;
|
||||
|
@ -100,6 +96,9 @@ public final class FabricDataGenHelper {
|
|||
DataGeneratorEntrypoint.class.getName(), ENTRYPOINT_KEY);
|
||||
}
|
||||
|
||||
// Load the registries synchronously
|
||||
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture = CompletableFuture.completedFuture(BuiltinRegistries.createWrapperLookup());
|
||||
|
||||
for (EntrypointContainer<DataGeneratorEntrypoint> entrypointContainer : dataGeneratorInitializers) {
|
||||
final String id = entrypointContainer.getProvider().getMetadata().getId();
|
||||
|
||||
|
@ -120,7 +119,7 @@ public final class FabricDataGenHelper {
|
|||
modContainer = FabricLoader.getInstance().getModContainer(effectiveModId).orElseThrow(() -> new RuntimeException("Failed to find effective mod container for mod id (%s)".formatted(effectiveModId)));
|
||||
}
|
||||
|
||||
FabricDataGenerator dataGenerator = new FabricDataGenerator(outputDir, modContainer, STRICT_VALIDATION);
|
||||
FabricDataGenerator dataGenerator = new FabricDataGenerator(outputDir, modContainer, STRICT_VALIDATION, registriesFuture);
|
||||
entrypoint.onInitializeDataGenerator(dataGenerator);
|
||||
dataGenerator.run();
|
||||
} catch (Throwable t) {
|
||||
|
@ -129,23 +128,6 @@ public final class FabricDataGenHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A fake registry instance to be used for {@link DynamicRegistryTagProvider}.
|
||||
*
|
||||
* <p>In {@link AbstractTagProvider#run}, it checks for whether the registry has all the elements added to the builder.
|
||||
* This would be fine for static registry, but there won't be any instance dynamic registry available.
|
||||
* Therefore, this simply return true for all {@link Registry#containsId} call.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static <T> Registry<T> getFakeDynamicRegistry(RegistryKey<? extends Registry<T>> registryKey) {
|
||||
return new SimpleRegistry<>(registryKey, Lifecycle.experimental(), false) {
|
||||
@Override
|
||||
public boolean containsId(Identifier id) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to keep track of conditions associated to generated objects.
|
||||
*/
|
||||
|
|
|
@ -19,6 +19,7 @@ package net.fabricmc.fabric.mixin.datagen;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
@ -37,7 +38,7 @@ import net.fabricmc.fabric.impl.datagen.FabricTagBuilder;
|
|||
@Mixin(AbstractTagProvider.class)
|
||||
public class AbstractTagProviderMixin {
|
||||
@Inject(method = "method_27046", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/DataOutput$PathResolver;resolveJson(Lnet/minecraft/util/Identifier;)Ljava/nio/file/Path;"), locals = LocalCapture.CAPTURE_FAILHARD)
|
||||
public void addReplaced(DataWriter dataWriter, Map.Entry<?, ?> entry, CallbackInfoReturnable<CompletableFuture<?>> ci, Identifier id, TagBuilder builder, List list, List list2, JsonElement jsonElement) {
|
||||
public void addReplaced(Predicate<?> p, DataWriter dataWriter, Map.Entry<?, ?> entry, CallbackInfoReturnable<CompletableFuture<?>> ci, Identifier id, TagBuilder builder, List list, List list2, JsonElement jsonElement) {
|
||||
if (builder instanceof FabricTagBuilder fabricTagBuilder) {
|
||||
jsonElement.getAsJsonObject().addProperty("replace", fabricTagBuilder.fabric_isReplaced());
|
||||
}
|
||||
|
|
|
@ -6,10 +6,9 @@ mutable field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOu
|
|||
accessible field net/minecraft/data/server/recipe/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
|
||||
accessible field net/minecraft/data/server/recipe/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
|
||||
|
||||
accessible method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder <init> (Lnet/minecraft/tag/TagBuilder;Lnet/minecraft/util/registry/Registry;)V
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Ljava/lang/Object;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder builder Lnet/minecraft/tag/TagBuilder;
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder registry Lnet/minecraft/util/registry/Registry;
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder method_46835 (Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider tagBuilders Ljava/util/Map;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ public class DataGeneratorTestContent implements ModInitializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void addItems(FeatureSet featureSet, Entries entries) {
|
||||
protected void addItems(FeatureSet featureSet, Entries entries, boolean showAdminItems) {
|
||||
entries.addAll(items);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import static net.fabricmc.fabric.test.datagen.DataGeneratorTestContent.SIMPLE_I
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
|
@ -34,7 +35,7 @@ import org.slf4j.LoggerFactory;
|
|||
import net.minecraft.advancement.Advancement;
|
||||
import net.minecraft.advancement.AdvancementFrame;
|
||||
import net.minecraft.advancement.criterion.OnKilledCriterion;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.util.registry.RegistryWrapper;
|
||||
import net.minecraft.data.client.BlockStateModelGenerator;
|
||||
import net.minecraft.data.client.ItemModelGenerator;
|
||||
import net.minecraft.data.server.recipe.RecipeJsonProvider;
|
||||
|
@ -54,7 +55,6 @@ import net.minecraft.tag.ItemTags;
|
|||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.BiomeKeys;
|
||||
|
@ -90,34 +90,8 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
pack.addProvider(JapaneseLangProvider::new);
|
||||
|
||||
TestBlockTagProvider blockTagProvider = pack.addProvider(TestBlockTagProvider::new);
|
||||
pack.addProvider((FabricDataGenerator.Pack.Factory<TestItemTagProvider>) output -> new TestItemTagProvider(output, blockTagProvider));
|
||||
pack.addProvider((output, registries) -> new TestItemTagProvider(output, registries, blockTagProvider));
|
||||
pack.addProvider(TestBiomeTagProvider::new);
|
||||
|
||||
try {
|
||||
pack.addProvider((FabricDataGenerator.Pack.Factory<DataProvider>) output -> {
|
||||
new FabricTagProvider<>(output, BuiltinRegistries.BIOME) {
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
}
|
||||
};
|
||||
throw new AssertionError("Using FabricTagProvider with built-in registry didn't throw an exception!");
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
try {
|
||||
pack.addProvider((FabricDataGenerator.Pack.Factory<DataProvider>) output -> {
|
||||
new FabricTagProvider.DynamicRegistryTagProvider<>(output, Registry.ITEM_KEY) {
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
}
|
||||
};
|
||||
throw new AssertionError("Using DynamicRegistryTagProvider with static registry didn't throw an exception!");
|
||||
});
|
||||
} catch (IllegalArgumentException e) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestRecipeProvider extends FabricRecipeProvider {
|
||||
|
@ -198,46 +172,39 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
|
|||
}
|
||||
|
||||
private static class TestBlockTagProvider extends FabricTagProvider.BlockTagProvider {
|
||||
private TestBlockTagProvider(FabricDataOutput output) {
|
||||
super(output);
|
||||
TestBlockTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(BlockTags.FIRE).add(SIMPLE_BLOCK);
|
||||
getOrCreateTagBuilder(BlockTags.ANVIL).setReplace(true).add(SIMPLE_BLOCK, BLOCK_WITHOUT_ITEM);
|
||||
getOrCreateTagBuilder(BlockTags.ANVIL).setReplace(true).add(SIMPLE_BLOCK);
|
||||
getOrCreateTagBuilder(BlockTags.ACACIA_LOGS).forceAddTag(BlockTags.ANIMALS_SPAWNABLE_ON);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestItemTagProvider extends FabricTagProvider.ItemTagProvider {
|
||||
private TestItemTagProvider(FabricDataOutput output, BlockTagProvider blockTagProvider) {
|
||||
super(output, blockTagProvider);
|
||||
private TestItemTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture, BlockTagProvider blockTagProvider) {
|
||||
super(output, registriesFuture, blockTagProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
copy(BlockTags.ANVIL, ItemTags.ANVIL);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestBiomeTagProvider extends FabricTagProvider.DynamicRegistryTagProvider<Biome> {
|
||||
private TestBiomeTagProvider(FabricDataOutput output) {
|
||||
super(output, Registry.BIOME_KEY);
|
||||
private static class TestBiomeTagProvider extends FabricTagProvider<Biome> {
|
||||
private TestBiomeTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
|
||||
super(output, Registry.BIOME_KEY, registriesFuture);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generateTags() {
|
||||
FabricTagBuilder<Biome> builder = getOrCreateTagBuilder(TagKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "biome_tag_test")))
|
||||
protected void configure(RegistryWrapper.WrapperLookup registries) {
|
||||
getOrCreateTagBuilder(TagKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "biome_tag_test")))
|
||||
.add(BiomeKeys.BADLANDS, BiomeKeys.BAMBOO_JUNGLE)
|
||||
.add(BiomeKeys.BASALT_DELTAS);
|
||||
|
||||
try {
|
||||
builder.add(BuiltinRegistries.BIOME.get(BiomeKeys.PLAINS));
|
||||
throw new AssertionError("Adding built-in entry to dynamic registry tag builder didn't throw an exception!");
|
||||
} catch (UnsupportedOperationException e) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,9 @@ mutable field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOu
|
|||
accessible field net/minecraft/data/server/recipe/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
|
||||
accessible field net/minecraft/data/server/recipe/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
|
||||
|
||||
accessible method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder <init> (Lnet/minecraft/tag/TagBuilder;Lnet/minecraft/util/registry/Registry;)V
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Ljava/lang/Object;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder builder Lnet/minecraft/tag/TagBuilder;
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder registry Lnet/minecraft/util/registry/Registry;
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder method_46835 (Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
|
||||
|
||||
accessible field net/minecraft/data/server/tag/AbstractTagProvider tagBuilders Ljava/util/Map;
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package net.fabricmc.fabric.test.dimension;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
|
@ -25,7 +24,7 @@ import com.mojang.serialization.Codec;
|
|||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.structure.StructureSet;
|
||||
import net.minecraft.util.registry.RegistryEntryLookup;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
@ -46,14 +45,11 @@ import net.minecraft.world.gen.noise.NoiseConfig;
|
|||
|
||||
public class VoidChunkGenerator extends ChunkGenerator {
|
||||
public static final Codec<VoidChunkGenerator> CODEC = RecordCodecBuilder.create((instance) ->
|
||||
createStructureSetRegistryGetter(instance).and(RegistryOps.createRegistryCodec(Registry.BIOME_KEY).forGetter((generator) -> generator.biomeRegistry))
|
||||
instance.group(RegistryOps.getEntryLookupCodec(Registry.BIOME_KEY))
|
||||
.apply(instance, instance.stable(VoidChunkGenerator::new)));
|
||||
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
|
||||
public VoidChunkGenerator(Registry<StructureSet> registry, Registry<Biome> biomeRegistry) {
|
||||
super(registry, Optional.empty(), new FixedBiomeSource(biomeRegistry.getOrCreateEntry(BiomeKeys.PLAINS)));
|
||||
this.biomeRegistry = biomeRegistry;
|
||||
public VoidChunkGenerator(RegistryEntryLookup<Biome> biomeRegistry) {
|
||||
super(new FixedBiomeSource(biomeRegistry.getOrThrow(BiomeKeys.PLAINS)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -40,10 +40,10 @@ public final class EnumRuleWidget<E extends Enum<E>> extends EditGameRulesScreen
|
|||
|
||||
// Base translation key needs to be set before the button widget is created.
|
||||
this.rootTranslationKey = translationKey;
|
||||
this.buttonWidget = ButtonWidget.method_46430(this.getValueText(rule.get()), (buttonWidget) -> {
|
||||
this.buttonWidget = ButtonWidget.createBuilder(this.getValueText(rule.get()), (buttonWidget) -> {
|
||||
rule.cycle();
|
||||
buttonWidget.setMessage(this.getValueText(rule.get()));
|
||||
}).method_46433(10, 5).method_46437(88, 20).method_46431();
|
||||
}).setPosition(10, 5).setSize(88, 20).build();
|
||||
|
||||
this.children.add(this.buttonWidget);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ public class FabricCreativeGuiComponents {
|
|||
final Type type;
|
||||
|
||||
public ItemGroupButtonWidget(int x, int y, Type type, CreativeGuiExtensions extensions) {
|
||||
super(x, y, 11, 10, type.text, (bw) -> type.clickConsumer.accept(extensions), EMPTY, ButtonWidget.field_40754);
|
||||
super(x, y, 11, 10, type.text, (bw) -> type.clickConsumer.accept(extensions), EMPTY_TOOLTIP, ButtonWidget.DEFAULT_NARRATION_SUPPLIER);
|
||||
this.extensions = extensions;
|
||||
this.type = type;
|
||||
this.gui = (CreativeInventoryScreen) extensions;
|
||||
|
@ -47,7 +47,7 @@ public class FabricCreativeGuiComponents {
|
|||
|
||||
@Override
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float float_1) {
|
||||
this.hovered = mouseX >= this.method_46426() && mouseY >= this.method_46427() && mouseX < this.method_46426() + this.width && mouseY < this.method_46427() + this.height;
|
||||
this.hovered = mouseX >= this.getX() && mouseY >= this.getY() && mouseX < this.getX() + this.width && mouseY < this.getY() + this.height;
|
||||
this.visible = extensions.fabric_isButtonVisible(type);
|
||||
this.active = extensions.fabric_isButtonEnabled(type);
|
||||
|
||||
|
@ -57,7 +57,7 @@ public class FabricCreativeGuiComponents {
|
|||
|
||||
RenderSystem.setShaderTexture(0, BUTTON_TEX);
|
||||
RenderSystem.setShaderColor(1F, 1F, 1F, 1F);
|
||||
this.drawTexture(matrixStack, this.method_46426(), this.method_46427(), u + (type == Type.NEXT ? 11 : 0), v, 11, 10);
|
||||
this.drawTexture(matrixStack, this.getX(), this.getY(), u + (type == Type.NEXT ? 11 : 0), v, 11, 10);
|
||||
|
||||
if (this.hovered) {
|
||||
int pageCount = (int) Math.ceil((ItemGroups.GROUPS.length - COMMON_GROUPS.size()) / 9D);
|
||||
|
|
|
@ -45,15 +45,15 @@ abstract class ItemGroupMixin implements IdentifiableItemGroup {
|
|||
@Final
|
||||
private int index;
|
||||
|
||||
@Shadow
|
||||
@Shadow(aliases = "field_40859")
|
||||
private ItemStackSet displayStacks;
|
||||
|
||||
@Shadow
|
||||
@Shadow(aliases = "field_40860")
|
||||
private ItemStackSet searchTabStacks;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Inject(method = "getStacks", at = @At(value = "FIELD", target = "Lnet/minecraft/item/ItemGroup;searchTabStacks:Lnet/minecraft/item/ItemStackSet;", opcode = Opcodes.PUTFIELD, shift = At.Shift.AFTER))
|
||||
public void getStacks(FeatureSet enabledFeatures, boolean search, CallbackInfoReturnable<ItemStackSet> cir) {
|
||||
public void getStacks(FeatureSet enabledFeatures, boolean search, boolean showAdminItems, CallbackInfoReturnable<ItemStackSet> cir) {
|
||||
// Sanity check for the injection point. It should be after these fields are set.
|
||||
Objects.requireNonNull(displayStacks, "displayStacks");
|
||||
Objects.requireNonNull(searchTabStacks, "searchTabStacks");
|
||||
|
|
|
@ -45,7 +45,7 @@ public class ItemGroupTest implements ModInitializer {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void addItems(FeatureSet featureSet, Entries entries) {
|
||||
protected void addItems(FeatureSet featureSet, Entries entries, boolean opItems) {
|
||||
entries.addAll(Registry.ITEM.stream()
|
||||
.map(ItemStack::new)
|
||||
.toList());
|
||||
|
|
|
@ -39,22 +39,22 @@ final class ChannelScreen extends Screen {
|
|||
|
||||
@Override
|
||||
protected void init() {
|
||||
this.s2cButton = this.addDrawableChild(ButtonWidget.method_46430(Text.literal("S2C"), this::toS2C)
|
||||
.method_46433(this.width / 2 - 55, 5)
|
||||
.method_46437(50, 20)
|
||||
.method_46436((button2, matrices1, mouseX1, mouseY1) -> {
|
||||
this.s2cButton = this.addDrawableChild(ButtonWidget.createBuilder(Text.literal("S2C"), this::toS2C)
|
||||
.setPosition(this.width / 2 - 55, 5)
|
||||
.setSize(50, 20)
|
||||
.setTooltipSupplier((button2, matrices1, mouseX1, mouseY1) -> {
|
||||
this.renderTooltip(matrices1, Text.literal("Packets this client can receive"), mouseX1, mouseY1);
|
||||
}).method_46431());
|
||||
this.c2sButton = this.addDrawableChild(ButtonWidget.method_46430(Text.literal("C2S"), this::toC2S)
|
||||
.method_46433(this.width / 2 + 5, 5)
|
||||
.method_46437(50, 20)
|
||||
.method_46436((button1, matrices, mouseX, mouseY) -> {
|
||||
}).build());
|
||||
this.c2sButton = this.addDrawableChild(ButtonWidget.createBuilder(Text.literal("C2S"), this::toC2S)
|
||||
.setPosition(this.width / 2 + 5, 5)
|
||||
.setSize(50, 20)
|
||||
.setTooltipSupplier((button1, matrices, mouseX, mouseY) -> {
|
||||
this.renderTooltip(matrices, Text.literal("Packets the server can receive"), mouseX, mouseY);
|
||||
}).method_46431());
|
||||
this.closeButton = this.addDrawableChild(ButtonWidget.method_46430(Text.literal("Close"), button -> this.close())
|
||||
.method_46433(this.width / 2 - 60, this.height - 25)
|
||||
.method_46437(120, 20)
|
||||
.method_46431());
|
||||
}).build());
|
||||
this.closeButton = this.addDrawableChild(ButtonWidget.createBuilder(Text.literal("Close"), button -> this.close())
|
||||
.setPosition(this.width / 2 - 60, this.height - 25)
|
||||
.setSize(120, 20)
|
||||
.build());
|
||||
this.channelList = this.addDrawable(new ChannelList(this.client, this.width, this.height - 60, 30, this.height - 30, this.textRenderer.fontHeight + 2));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,66 +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.registry.sync;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.fabric.mixin.registry.sync.RegistryAccessor;
|
||||
|
||||
/**
|
||||
* Handles synchronising changes to the built-in registries into the dynamic registry manager's template manager,
|
||||
* in case it gets classloaded early.
|
||||
*/
|
||||
public class DynamicRegistrySync {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicRegistrySync.class);
|
||||
|
||||
/**
|
||||
* Sets up a synchronisation that will propagate added entries to the given dynamic registry manager, which
|
||||
* should be the <em>built-in</em> manager. It is never destroyed. We don't ever have to unregister
|
||||
* the registry events.
|
||||
*/
|
||||
public static void setupSync(DynamicRegistryManager template) {
|
||||
LOGGER.debug("Setting up synchronisation of new BuiltinRegistries entries to the built-in DynamicRegistryManager");
|
||||
BuiltinRegistries.REGISTRIES.stream().forEach(source -> setupSync(source, template));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up an event registration for the source registy that will ensure all entries added from now on
|
||||
* are also added to the template for dynamic registry managers.
|
||||
*/
|
||||
private static <T> void setupSync(Registry<T> source, DynamicRegistryManager template) {
|
||||
@SuppressWarnings("unchecked") RegistryAccessor<T> sourceAccessor = (RegistryAccessor<T>) source;
|
||||
RegistryKey<? extends Registry<T>> sourceKey = source.getKey();
|
||||
MutableRegistry<T> target = (MutableRegistry<T>) template.get(sourceKey);
|
||||
|
||||
RegistryEntryAddedCallback.event(source).register((rawId, id, object) -> {
|
||||
LOGGER.trace("Synchronizing {} from built-in registry {} into built-in dynamic registry manager template.",
|
||||
id, source.getKey());
|
||||
Lifecycle lifecycle = sourceAccessor.callGetEntryLifecycle(object);
|
||||
RegistryKey<T> entryKey = RegistryKey.of(sourceKey, id);
|
||||
target.set(rawId, entryKey, object, lifecycle);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,33 +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.mixin.registry.sync;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
@Mixin(BuiltinRegistries.class)
|
||||
public class BuiltinRegistriesMixin {
|
||||
@Redirect(method = "<clinit>", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/registry/Registry;freeze()Lnet/minecraft/util/registry/Registry;"))
|
||||
private static Registry<?> unfreezeBultinRegistries(Registry<?> reg) {
|
||||
// Don't freeze
|
||||
return reg;
|
||||
}
|
||||
}
|
|
@ -25,9 +25,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.fabric.impl.registry.sync.trackers.vanilla.BlockInitTracker;
|
||||
|
@ -43,11 +41,6 @@ public class MinecraftServerMixin {
|
|||
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
|
||||
// Freeze the registries on the server
|
||||
FABRIC_LOGGER.debug("Freezing registries");
|
||||
BuiltinRegistries.REGISTRIES.freeze();
|
||||
|
||||
for (Registry<?> registry : BuiltinRegistries.REGISTRIES) {
|
||||
((SimpleRegistry<?>) registry).freeze();
|
||||
}
|
||||
|
||||
Registry.freezeRegistries();
|
||||
BlockInitTracker.postFreeze();
|
||||
|
|
|
@ -16,9 +16,13 @@
|
|||
|
||||
package net.fabricmc.fabric.mixin.registry.sync;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
|
@ -26,7 +30,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.dynamic.RegistryOps;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.MutableRegistry;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.util.registry.RegistryLoader;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback;
|
||||
|
@ -42,7 +50,33 @@ public class RegistryLoaderMixin {
|
|||
),
|
||||
locals = LocalCapture.CAPTURE_FAILHARD
|
||||
)
|
||||
private static void beforeLoad(ResourceManager resourceManager, DynamicRegistryManager baseRegistryManager, List<RegistryLoader.Entry<?>> entries, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir, Map a, List b, DynamicRegistryManager registryManager) {
|
||||
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(registryManager);
|
||||
private static void beforeLoad(ResourceManager resourceManager, DynamicRegistryManager baseRegistryManager, List<RegistryLoader.Entry<?>> entries, CallbackInfoReturnable<DynamicRegistryManager.Immutable> cir, Map a, List<Pair<MutableRegistry<?>, ?>> registriesList, RegistryOps.RegistryInfoGetter registryManager) {
|
||||
Map<RegistryKey<? extends Registry<?>>, Registry<?>> registries = new IdentityHashMap<>(registriesList.size());
|
||||
|
||||
for (Pair<MutableRegistry<?>, ?> pair : registriesList) {
|
||||
registries.put(pair.getFirst().getKey(), pair.getFirst());
|
||||
}
|
||||
|
||||
DynamicRegistryManager drm = new DynamicRegistryManager.Immutable() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Optional<Registry<T>> getOptional(RegistryKey<? extends Registry<? extends T>> key) {
|
||||
return Optional.ofNullable((Registry<T>) registries.get(key));
|
||||
}
|
||||
|
||||
public Stream<Entry<?>> streamAllRegistries() {
|
||||
return registries.values().stream()
|
||||
.map(this::entry);
|
||||
}
|
||||
|
||||
private <T> Entry<T> entry(Registry<T> registry) {
|
||||
return new Entry<>(registry.getKey(), registry);
|
||||
}
|
||||
|
||||
public Immutable toImmutable() {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
DynamicRegistrySetupCallback.EVENT.invoker().onRegistrySetup(drm);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"BootstrapMixin",
|
||||
"BuiltinRegistriesMixin",
|
||||
"ChunkSerializerMixin",
|
||||
"DebugChunkGeneratorAccessor",
|
||||
"IdListMixin",
|
||||
|
|
|
@ -30,13 +30,8 @@ import net.minecraft.block.Material;
|
|||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.DynamicRegistryManager;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.SimpleRegistry;
|
||||
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||
|
@ -88,8 +83,6 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
sender.sendPacket(PACKET_CHECK_COMPARE, PacketByteBufs.empty());
|
||||
});
|
||||
|
||||
testBuiltInRegistrySync();
|
||||
|
||||
if (REGISTER_BLOCKS) {
|
||||
// For checking raw id bulk in direct registry packet, make registry_sync namespace have two bulks.
|
||||
registerBlocks("registry_sync", 5, 0);
|
||||
|
@ -147,45 +140,4 @@ public class RegistrySyncTest implements ModInitializer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that built-in registries are properly synchronized even after the dynamic reigstry managers have been
|
||||
* class-loaded.
|
||||
*/
|
||||
private void testBuiltInRegistrySync() {
|
||||
LOGGER.info("Checking built-in registry sync...");
|
||||
|
||||
// Register a configured feature before force-loading the dynamic registry manager
|
||||
ConfiguredFeature<DefaultFeatureConfig, ?> cf1 = new ConfiguredFeature<>(Feature.BASALT_PILLAR, DefaultFeatureConfig.INSTANCE);
|
||||
Identifier f1Id = new Identifier("registry_sync", "f1");
|
||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, f1Id, cf1);
|
||||
|
||||
// Force-Initialize the dynamic registry manager, doing this in a Mod initializer would cause
|
||||
// further registrations into BuiltInRegistries to _NOT_ propagate into DynamicRegistryManager.BUILTIN
|
||||
checkFeature(DynamicRegistryManager.of(BuiltinRegistries.REGISTRIES), f1Id);
|
||||
|
||||
ConfiguredFeature<DefaultFeatureConfig, ?> cf2 = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE);
|
||||
Identifier f2Id = new Identifier("registry_sync", "f2");
|
||||
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, f2Id, cf2);
|
||||
|
||||
DynamicRegistryManager impl2 = DynamicRegistryManager.of(BuiltinRegistries.REGISTRIES);
|
||||
checkFeature(impl2, f1Id);
|
||||
checkFeature(impl2, f2Id);
|
||||
}
|
||||
|
||||
private void checkFeature(DynamicRegistryManager manager, Identifier id) {
|
||||
Registry<ConfiguredFeature<?, ?>> registry = manager.get(Registry.CONFIGURED_FEATURE_KEY);
|
||||
|
||||
ConfiguredFeature<?, ?> builtInEntry = BuiltinRegistries.CONFIGURED_FEATURE.get(id);
|
||||
|
||||
if (builtInEntry == null) {
|
||||
throw new IllegalStateException("Expected built-in entry to exist for: " + id);
|
||||
}
|
||||
|
||||
ConfiguredFeature<?, ?> entry = registry.get(id);
|
||||
|
||||
if (entry == null) {
|
||||
throw new IllegalStateException("Expected dynamic registry to contain entry " + id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ import net.minecraft.fluid.FluidState;
|
|||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.screen.PlayerScreenHandler;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraft.world.biome.BiomeKeys;
|
||||
|
||||
|
@ -42,7 +41,10 @@ import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler;
|
|||
import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry;
|
||||
|
||||
public class FluidRenderHandlerRegistryImpl implements FluidRenderHandlerRegistry {
|
||||
private static final int DEFAULT_WATER_COLOR = BuiltinRegistries.BIOME.get(BiomeKeys.OCEAN).getWaterColor();
|
||||
/**
|
||||
* The water color of {@link BiomeKeys#OCEAN}.
|
||||
*/
|
||||
private static final int DEFAULT_WATER_COLOR = 0x3f76e4;
|
||||
private final Map<Fluid, FluidRenderHandler> handlers = new IdentityHashMap<>();
|
||||
private final Map<Fluid, FluidRenderHandler> modHandlers = new IdentityHashMap<>();
|
||||
private final Map<Block, Boolean> overlayBlocks = new IdentityHashMap<>();
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.state.StateManager;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.WorldView;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public abstract class CustomFluid extends FlowableFluid {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInfinite() {
|
||||
protected boolean isInfinite(World world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.state.StateManager;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.WorldView;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public abstract class NoOverlayFluid extends FlowableFluid {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInfinite() {
|
||||
protected boolean isInfinite(World world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.state.StateManager;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.WorldView;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public abstract class OverlayFluid extends FlowableFluid {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInfinite() {
|
||||
protected boolean isInfinite(World world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import net.minecraft.state.StateManager;
|
|||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldAccess;
|
||||
import net.minecraft.world.WorldView;
|
||||
|
||||
|
@ -56,7 +57,7 @@ public abstract class UnregisteredFluid extends FlowableFluid {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInfinite() {
|
||||
protected boolean isInfinite(World world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ class StopSoundButton extends PressableWidget {
|
|||
public void render(MatrixStack matrices, int mouseX, int mouseY, float tickDelta) {
|
||||
// Render the armor icon to test
|
||||
RenderSystem.setShaderTexture(0, InGameHud.GUI_ICONS_TEXTURE);
|
||||
DrawableHelper.drawTexture(matrices, this.method_46426(), this.method_46427(), this.width, this.height, 43, 27, 9, 9, 256, 256);
|
||||
DrawableHelper.drawTexture(matrices, this.getX(), this.getY(), this.width, this.height, 43, 27, 9, 9, 256, 256);
|
||||
|
||||
if (this.isMouseOver(mouseX, mouseY)) {
|
||||
this.screen.renderTooltip(matrices, Text.literal("Click to stop all sounds"), this.method_46426(), this.method_46427());
|
||||
this.screen.renderTooltip(matrices, Text.literal("Click to stop all sounds"), this.getX(), this.getY());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ transitive-accessible method net/minecraft/block/FarmlandBlock <init> (Lnet/mine
|
|||
transitive-accessible method net/minecraft/block/FernBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
transitive-accessible method net/minecraft/block/FletchingTableBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
transitive-accessible method net/minecraft/block/FluidBlock <init> (Lnet/minecraft/fluid/FlowableFluid;Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
transitive-accessible method net/minecraft/block/FungusBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;Ljava/util/function/Supplier;)V
|
||||
transitive-accessible method net/minecraft/block/FungusBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;Lnet/minecraft/util/registry/RegistryKey;)V
|
||||
transitive-accessible method net/minecraft/block/FurnaceBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
transitive-accessible method net/minecraft/block/GrindstoneBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
transitive-accessible method net/minecraft/block/HangingRootsBlock <init> (Lnet/minecraft/block/AbstractBlock$Settings;)V
|
||||
|
|
|
@ -1,60 +1,60 @@
|
|||
org.gradle.jvmargs=-Xmx2560M
|
||||
org.gradle.parallel=true
|
||||
|
||||
version=0.65.2
|
||||
minecraft_version=22w43a
|
||||
yarn_version=+build.3
|
||||
version=0.65.3
|
||||
minecraft_version=22w44a
|
||||
yarn_version=+build.4
|
||||
loader_version=0.14.10
|
||||
|
||||
prerelease=true
|
||||
|
||||
# Do not manually update, use the bumpversions task:
|
||||
fabric-api-base-version=0.4.14
|
||||
fabric-api-lookup-api-v1-version=1.6.12
|
||||
fabric-biome-api-v1-version=10.0.1
|
||||
fabric-blockrenderlayer-v1-version=1.1.23
|
||||
fabric-command-api-v1-version=1.2.14
|
||||
fabric-command-api-v2-version=2.1.10
|
||||
fabric-commands-v0-version=0.2.31
|
||||
fabric-containers-v0-version=0.1.37
|
||||
fabric-content-registries-v0-version=3.4.3
|
||||
fabric-crash-report-info-v1-version=0.2.8
|
||||
fabric-data-generation-api-v1-version=8.0.0
|
||||
fabric-dimensions-v1-version=2.1.34
|
||||
fabric-entity-events-v1-version=1.4.21
|
||||
fabric-events-interaction-v0-version=0.4.31
|
||||
fabric-events-lifecycle-v0-version=0.2.31
|
||||
fabric-game-rule-api-v1-version=1.0.24
|
||||
fabric-gametest-api-v1-version=1.1.4
|
||||
fabric-item-api-v1-version=2.0.1
|
||||
fabric-item-group-api-v1-version=1.0.2
|
||||
fabric-key-binding-api-v1-version=1.0.24
|
||||
fabric-keybindings-v0-version=0.2.22
|
||||
fabric-lifecycle-events-v1-version=2.2.2
|
||||
fabric-loot-api-v2-version=1.1.9
|
||||
fabric-loot-tables-v1-version=1.1.12
|
||||
fabric-message-api-v1-version=5.0.7
|
||||
fabric-mining-level-api-v1-version=2.1.20
|
||||
fabric-models-v0-version=0.3.20
|
||||
fabric-networking-api-v1-version=1.2.7
|
||||
fabric-networking-v0-version=0.3.24
|
||||
fabric-object-builder-api-v1-version=5.0.1
|
||||
fabric-particles-v1-version=1.0.13
|
||||
fabric-registry-sync-v0-version=1.0.0
|
||||
fabric-renderer-api-v1-version=2.0.0
|
||||
fabric-renderer-indigo-version=0.6.16
|
||||
fabric-renderer-registries-v1-version=3.2.23
|
||||
fabric-rendering-data-attachment-v1-version=0.3.17
|
||||
fabric-rendering-fluids-v1-version=3.0.10
|
||||
fabric-rendering-v0-version=1.1.25
|
||||
fabric-rendering-v1-version=1.11.2
|
||||
fabric-resource-conditions-api-v1-version=2.1.2
|
||||
fabric-resource-loader-v0-version=0.9.0
|
||||
fabric-screen-api-v1-version=1.0.29
|
||||
fabric-screen-handler-api-v1-version=1.3.3
|
||||
fabric-sound-api-v1-version=1.0.2
|
||||
fabric-textures-v0-version=2.0.1
|
||||
fabric-transfer-api-v1-version=2.1.3
|
||||
fabric-transitive-access-wideners-v1-version=2.0.0
|
||||
fabric-convention-tags-v1-version=1.1.4
|
||||
fabric-client-tags-api-v1-version=1.0.4
|
||||
fabric-api-base-version=0.4.15
|
||||
fabric-api-lookup-api-v1-version=1.6.13
|
||||
fabric-biome-api-v1-version=11.0.0
|
||||
fabric-blockrenderlayer-v1-version=1.1.24
|
||||
fabric-command-api-v1-version=1.2.15
|
||||
fabric-command-api-v2-version=2.1.11
|
||||
fabric-commands-v0-version=0.2.32
|
||||
fabric-containers-v0-version=0.1.38
|
||||
fabric-content-registries-v0-version=3.4.4
|
||||
fabric-crash-report-info-v1-version=0.2.9
|
||||
fabric-data-generation-api-v1-version=9.0.0
|
||||
fabric-dimensions-v1-version=2.1.35
|
||||
fabric-entity-events-v1-version=1.4.22
|
||||
fabric-events-interaction-v0-version=0.4.32
|
||||
fabric-events-lifecycle-v0-version=0.2.32
|
||||
fabric-game-rule-api-v1-version=1.0.25
|
||||
fabric-gametest-api-v1-version=1.1.5
|
||||
fabric-item-api-v1-version=2.0.2
|
||||
fabric-item-group-api-v1-version=1.0.3
|
||||
fabric-key-binding-api-v1-version=1.0.25
|
||||
fabric-keybindings-v0-version=0.2.23
|
||||
fabric-lifecycle-events-v1-version=2.2.3
|
||||
fabric-loot-api-v2-version=1.1.10
|
||||
fabric-loot-tables-v1-version=1.1.13
|
||||
fabric-message-api-v1-version=5.0.8
|
||||
fabric-mining-level-api-v1-version=2.1.21
|
||||
fabric-models-v0-version=0.3.21
|
||||
fabric-networking-api-v1-version=1.2.8
|
||||
fabric-networking-v0-version=0.3.25
|
||||
fabric-object-builder-api-v1-version=5.0.2
|
||||
fabric-particles-v1-version=1.0.14
|
||||
fabric-registry-sync-v0-version=1.0.1
|
||||
fabric-renderer-api-v1-version=2.0.1
|
||||
fabric-renderer-indigo-version=0.6.17
|
||||
fabric-renderer-registries-v1-version=3.2.24
|
||||
fabric-rendering-data-attachment-v1-version=0.3.18
|
||||
fabric-rendering-fluids-v1-version=3.0.11
|
||||
fabric-rendering-v0-version=1.1.26
|
||||
fabric-rendering-v1-version=1.11.3
|
||||
fabric-resource-conditions-api-v1-version=2.1.3
|
||||
fabric-resource-loader-v0-version=0.9.1
|
||||
fabric-screen-api-v1-version=1.0.30
|
||||
fabric-screen-handler-api-v1-version=1.3.4
|
||||
fabric-sound-api-v1-version=1.0.3
|
||||
fabric-textures-v0-version=2.0.2
|
||||
fabric-transfer-api-v1-version=2.1.4
|
||||
fabric-transitive-access-wideners-v1-version=2.0.1
|
||||
fabric-convention-tags-v1-version=1.1.5
|
||||
fabric-client-tags-api-v1-version=1.0.5
|
||||
|
|
Loading…
Reference in a new issue