This commit is contained in:
Player 2022-03-17 00:16:03 +01:00
parent 08b1b79b17
commit 7463d67c85
32 changed files with 220 additions and 177 deletions
fabric-api-lookup-api-v1/src/main/java/net/fabricmc/fabric/impl/lookup/entity
fabric-biome-api-v1/src
fabric-command-api-v1/src/main/java/net/fabricmc/fabric/mixin/command
fabric-data-generation-api-v1/src
main
java/net/fabricmc/fabric/api/datagen/v1/provider
resources
testmod/java/net/fabricmc/fabric/test/datagen
fabric-dimensions-v1/src/testmod/java/net/fabricmc/fabric/test/dimension
fabric-events-interaction-v0/src/main/java/net/fabricmc/fabric/mixin/event/interaction
fabric-gametest-api-v1/src/main/java/net/fabricmc/fabric/mixin/gametest
fabric-mining-level-api-v1/src/main/java/net/fabricmc/fabric/impl/mininglevel
fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric
fabric-screen-api-v1/src/main/java/net/fabricmc/fabric/mixin/screen
gradle.properties
src/main/resources

View file

@ -42,7 +42,7 @@ import net.fabricmc.fabric.api.lookup.v1.entity.EntityApiLookup;
public class EntityApiLookupImpl<A, C> implements EntityApiLookup<A, C> {
private static final Logger LOGGER = LoggerFactory.getLogger("fabric-api-lookup-api-v1/entity");
private static final ApiLookupMap<EntityApiLookup<?, ?>> LOOKUPS = ApiLookupMap.create(EntityApiLookupImpl::new);
private static final ApiLookupMap<EntityApiLookup<?, ?>> LOOKUPS = ApiLookupMap.<EntityApiLookup<?, ?>>create(EntityApiLookupImpl::new);
private static final Map<Class<?>, Set<EntityType<?>>> REGISTERED_SELVES = new HashMap<>();
private static boolean checkEntityLookup = true;

View file

@ -45,12 +45,6 @@ import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
* <p><b>Experimental feature</b>, may be removed or changed without further notice.
*/
public interface BiomeModificationContext {
/**
* @see Biome#getCategory()
* @see Biome.Builder#category(Biome.Category)
*/
void setCategory(Biome.Category category);
/**
* Returns the modification context for the biomes weather properties.
*/

View file

@ -26,8 +26,8 @@ import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.feature.StructureFeature;
import net.fabricmc.fabric.impl.biome.modification.BuiltInRegistryKeys;
@ -121,8 +121,8 @@ public interface BiomeSelectionContext {
*
* <p>This method is intended for use with the Vanilla configured structures found in {@link net.minecraft.world.gen.feature.ConfiguredStructureFeatures}.
*/
default boolean validForBuiltInStructure(ConfiguredStructureFeature<?, ?> configuredStructure) {
RegistryKey<ConfiguredStructureFeature<?, ?>> key = BuiltInRegistryKeys.get(configuredStructure);
default boolean validForBuiltInStructure(StructureFeature structureFeature) {
RegistryKey<StructureFeature> key = BuiltInRegistryKeys.get(structureFeature);
return validForStructure(key);
}
@ -130,14 +130,14 @@ public interface BiomeSelectionContext {
* Returns true if the configured structure with the given key can start in this biome in any chunk generator
* used by the current world-save.
*/
boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key);
boolean validForStructure(RegistryKey<StructureFeature> key);
/**
* Tries to retrieve the registry key for the given configured feature, which should be from this biomes
* current structure list. May be empty if the configured feature is not registered, or does not come
* from this biomes feature list.
*/
Optional<RegistryKey<ConfiguredStructureFeature<?, ?>>> getStructureKey(ConfiguredStructureFeature<?, ?> configuredStructure);
Optional<RegistryKey<StructureFeature>> getStructureKey(StructureFeature structureFeature);
/**
* Tries to determine whether this biome generates in a specific dimension, based on the {@link net.minecraft.world.gen.GeneratorOptions}

View file

@ -17,16 +17,14 @@
package net.fabricmc.fabric.api.biome.v1;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Set;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableSet;
import net.minecraft.tag.TagKey;
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;
@ -167,16 +165,4 @@ public final class BiomeSelectors {
return false;
};
}
/**
* Matches Biomes that have one of the given categories.
*
* @see Biome#getCategory()
*/
public static Predicate<BiomeSelectionContext> categories(Biome.Category... categories) {
Set<Biome.Category> categorySet = EnumSet.noneOf(Biome.Category.class);
Collections.addAll(categorySet, categories);
return context -> categorySet.contains(context.getBiome().category);
}
}

View file

@ -18,6 +18,9 @@ package net.fabricmc.fabric.impl.biome;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.WeakHashMap;
import javax.annotation.Nullable;
import com.google.common.base.Preconditions;
import org.jetbrains.annotations.ApiStatus;
@ -29,6 +32,7 @@ import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeKeys;
import net.minecraft.world.biome.source.TheEndBiomeSource;
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
import net.minecraft.world.gen.random.AtomicSimpleRandom;
import net.minecraft.world.gen.random.ChunkRandom;
@ -79,28 +83,30 @@ public final class TheEndBiomeData {
END_BARRENS_MAP.computeIfAbsent(highlands, key -> new WeightedPicker<>()).add(barrens, weight);
}
public static Overrides createOverrides(Registry<Biome> biomeRegistry, long seed) {
return new Overrides(biomeRegistry, seed);
public static Overrides createOverrides(Registry<Biome> biomeRegistry) {
return new Overrides(biomeRegistry);
}
/**
* An instance of this class is attached to each {@link TheEndBiomeSource}.
*/
public static class Overrides {
private final PerlinNoiseSampler sampler;
// Vanilla entries to compare against
private final RegistryEntry<Biome> endMidlands;
private final RegistryEntry<Biome> endBarrens;
private final RegistryEntry<Biome> endHighlands;
// Maps where the keys have been resolved to actual entries
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBiomesMap;
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endMidlandsMap;
private final Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBarrensMap;
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBiomesMap;
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endMidlandsMap;
private final @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> endBarrensMap;
public Overrides(Registry<Biome> biomeRegistry, long seed) {
this.sampler = new PerlinNoiseSampler(new ChunkRandom(new AtomicSimpleRandom(seed)));
// cache for our own sampler (used for random biome replacement selection)
private final Map<MultiNoiseUtil.MultiNoiseSampler, PerlinNoiseSampler> samplers = new WeakHashMap<>();
// current seed, set from ChunkGenerator hook since it is not normally available
private static ThreadLocal<Long> seed = new ThreadLocal<>();
public Overrides(Registry<Biome> biomeRegistry) {
this.endMidlands = biomeRegistry.entryOf(BiomeKeys.END_MIDLANDS);
this.endBarrens = biomeRegistry.entryOf(BiomeKeys.END_BARRENS);
this.endHighlands = biomeRegistry.entryOf(BiomeKeys.END_HIGHLANDS);
@ -111,40 +117,60 @@ public final class TheEndBiomeData {
}
// Resolves all RegistryKey instances to RegistryEntries
private Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(Registry<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides) {
var result = new IdentityHashMap<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>>(overrides.size());
private @Nullable Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> resolveOverrides(Registry<Biome> biomeRegistry, Map<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> overrides) {
Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> result = new IdentityHashMap<>(overrides.size());
for (Map.Entry<RegistryKey<Biome>, WeightedPicker<RegistryKey<Biome>>> entry : overrides.entrySet()) {
result.put(biomeRegistry.entryOf(entry.getKey()), entry.getValue().map(biomeRegistry::entryOf));
WeightedPicker<RegistryKey<Biome>> picker = entry.getValue();
if (picker.getEntryCount() <= 1) continue; // don't use no-op entries
result.put(biomeRegistry.entryOf(entry.getKey()), picker.map(biomeRegistry::entryOf));
}
return result;
return result.isEmpty() ? null : result;
}
public RegistryEntry<Biome> pick(int x, int y, int z, RegistryEntry<Biome> vanillaBiome) {
RegistryEntry<Biome> replacementKey;
// The x and z of the entry are divided by 64 to ensure custom biomes are large enough; going larger than this]
// seems to make custom biomes too hard to find.
public RegistryEntry<Biome> pick(int x, int y, int z, MultiNoiseUtil.MultiNoiseSampler noise, RegistryEntry<Biome> vanillaBiome) {
if (vanillaBiome == endMidlands || vanillaBiome == endBarrens) {
// Since the highlands picker is statically populated by InternalBiomeData, picker will never be null.
WeightedPicker<RegistryEntry<Biome>> highlandsPicker = endBiomesMap.get(endHighlands);
RegistryEntry<Biome> highlandsKey = highlandsPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
// select a random highlands biome replacement, then try to replace it with a midlands or barrens biome replacement
RegistryEntry<Biome> highlandsReplacement = pick(endHighlands, endHighlands, endBiomesMap, x, z, noise);
Map<RegistryEntry<Biome>, WeightedPicker<RegistryEntry<Biome>>> map = vanillaBiome == endMidlands ? endMidlandsMap : endBarrensMap;
if (vanillaBiome == endMidlands) {
WeightedPicker<RegistryEntry<Biome>> midlandsPicker = endMidlandsMap.get(highlandsKey);
replacementKey = (midlandsPicker == null) ? vanillaBiome : midlandsPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
} else {
WeightedPicker<RegistryEntry<Biome>> barrensPicker = endBarrensMap.get(highlandsKey);
replacementKey = (barrensPicker == null) ? vanillaBiome : barrensPicker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
}
return pick(highlandsReplacement, vanillaBiome, map, x, z, noise);
} else {
// Since the main island and small islands pickers are statically populated by InternalBiomeData, picker will never be null.
WeightedPicker<RegistryEntry<Biome>> picker = endBiomesMap.get(vanillaBiome);
replacementKey = picker.pickFromNoise(sampler, x / 64.0, 0, z / 64.0);
assert END_BIOMES_MAP.containsKey(vanillaBiome.getKey().orElseThrow());
return pick(vanillaBiome, vanillaBiome, endBiomesMap, x, z, noise);
}
}
private <T> T pick(T key, T defaultValue, Map<T, WeightedPicker<T>> pickers, int x, int z, MultiNoiseUtil.MultiNoiseSampler noise) {
if (pickers == null) return defaultValue;
WeightedPicker<T> picker = pickers.get(key);
if (picker == null || picker.getEntryCount() <= 1) return defaultValue;
// The x and z of the entry are divided by 64 to ensure custom biomes are large enough; going larger than this
// seems to make custom biomes too hard to find.
return picker.pickFromNoise(getSampler(noise), x / 64.0, 0, z / 64.0);
}
private synchronized PerlinNoiseSampler getSampler(MultiNoiseUtil.MultiNoiseSampler noise) {
PerlinNoiseSampler ret = samplers.get(noise);
if (ret == null) {
Long seed = Overrides.seed.get();
if (seed == null) throw new IllegalStateException("seed isn't set, ChunkGenerator hook not working?");
ret = new PerlinNoiseSampler(new ChunkRandom(new AtomicSimpleRandom(seed)));
samplers.put(noise, ret);
}
return replacementKey;
return ret;
}
public static void setSeed(long seed) {
Overrides.seed.set(seed);
}
}
}

View file

@ -50,6 +50,10 @@ public final class WeightedPicker<T> {
return currentTotal;
}
int getEntryCount() {
return entries.size();
}
public T pickFromNoise(PerlinNoiseSampler sampler, double x, double y, double z) {
double target = Math.abs(sampler.sample(x, y, z)) * getCurrentWeightTotal();

View file

@ -33,8 +33,6 @@ import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import net.minecraft.util.registry.RegistryEntry;
import net.minecraft.util.registry.RegistryEntryList;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.sound.BiomeAdditionsSound;
@ -44,6 +42,8 @@ import net.minecraft.sound.SoundEvent;
import net.minecraft.util.collection.Pool;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryEntry;
import net.minecraft.util.registry.RegistryEntryList;
import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeEffects;
@ -52,9 +52,9 @@ import net.minecraft.world.biome.GenerationSettings;
import net.minecraft.world.biome.SpawnSettings;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.carver.ConfiguredCarver;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.feature.StructureFeature;
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
@ -78,11 +78,6 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
this.spawnSettings = new SpawnSettingsContextImpl();
}
@Override
public void setCategory(Biome.Category category) {
biome.category = category;
}
@Override
public WeatherContext getWeather() {
return weather;
@ -202,7 +197,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
private class GenerationSettingsContextImpl implements GenerationSettingsContext {
private final Registry<ConfiguredCarver<?>> carvers = registries.get(Registry.CONFIGURED_CARVER_KEY);
private final Registry<PlacedFeature> features = registries.get(Registry.PLACED_FEATURE_KEY);
private final Registry<ConfiguredStructureFeature<?, ?>> structures = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
private final Registry<StructureFeature> structures = registries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
private final GenerationSettings generationSettings = biome.getGenerationSettings();
private boolean rebuildFlowerFeatures;

View file

@ -28,8 +28,8 @@ import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.feature.StructureFeature;
import net.minecraft.world.level.LevelProperties;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
@ -78,20 +78,20 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
}
@Override
public boolean validForStructure(RegistryKey<ConfiguredStructureFeature<?, ?>> key) {
ConfiguredStructureFeature<?, ?> instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
public boolean validForStructure(RegistryKey<StructureFeature> key) {
StructureFeature instance = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY).get(key);
if (instance == null) {
return false;
}
return instance.getBiomes().contains(getBiomeRegistryEntry());
return instance.method_41607().contains(getBiomeRegistryEntry());
}
@Override
public Optional<RegistryKey<ConfiguredStructureFeature<?, ?>>> getStructureKey(ConfiguredStructureFeature<?, ?> configuredStructure) {
Registry<ConfiguredStructureFeature<?, ?>> registry = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
return registry.getKey(configuredStructure);
public Optional<RegistryKey<StructureFeature>> getStructureKey(StructureFeature structureFeature) {
Registry<StructureFeature> registry = dynamicRegistries.get(Registry.CONFIGURED_STRUCTURE_FEATURE_KEY);
return registry.getKey(structureFeature);
}
@Override

View file

@ -22,8 +22,8 @@ import net.minecraft.util.registry.BuiltinRegistries;
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.ConfiguredStructureFeature;
import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.feature.StructureFeature;
/**
* Utility class for getting the registry keys of built-in worldgen objects and throwing proper exceptions if they
@ -34,9 +34,9 @@ public final class BuiltInRegistryKeys {
private BuiltInRegistryKeys() {
}
public static RegistryKey<ConfiguredStructureFeature<?, ?>> get(ConfiguredStructureFeature<?, ?> configuredStructure) {
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(configuredStructure)
.orElseThrow(() -> new IllegalArgumentException("Given configured structure is not built-in: " + configuredStructure));
public static RegistryKey<StructureFeature> get(StructureFeature structureFeature) {
return BuiltinRegistries.CONFIGURED_STRUCTURE_FEATURE.getKey(structureFeature)
.orElseThrow(() -> new IllegalArgumentException("Given structure is not built-in: " + structureFeature));
}
public static RegistryKey<ConfiguredFeature<?, ?>> get(ConfiguredFeature<?, ?> configuredFeature) {

View file

@ -0,0 +1,37 @@
/*
* 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.biome;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.class_7138;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.fabricmc.fabric.impl.biome.TheEndBiomeData;
@Mixin(ChunkGenerator.class)
public class MixinChunkGenerator {
@Inject(method = "method_38267", at = @At("HEAD"))
private void populateBiomes_lambda_head(Chunk chunk, class_7138 rng, CallbackInfoReturnable<Chunk> ci) {
// capture seed so TheEndBiomeData.Overrides has it if it needs it
TheEndBiomeData.Overrides.setSeed(rng.legacyLevelSeed());
}
}

View file

@ -37,12 +37,12 @@ public class MixinTheEndBiomeSource {
private TheEndBiomeData.Overrides overrides;
@Inject(method = "<init>", at = @At("RETURN"))
private void init(Registry<Biome> biomeRegistry, long seed, CallbackInfo ci) {
overrides = TheEndBiomeData.createOverrides(biomeRegistry, seed);
private void init(Registry<Biome> biomeRegistry, CallbackInfo ci) {
overrides = TheEndBiomeData.createOverrides(biomeRegistry);
}
@Inject(method = "getBiome", at = @At("RETURN"), cancellable = true)
private void getWeightedEndBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseUtil.MultiNoiseSampler multiNoiseSampler, CallbackInfoReturnable<RegistryEntry<Biome>> cir) {
cir.setReturnValue(overrides.pick(biomeX, biomeY, biomeZ, cir.getReturnValue()));
private void getWeightedEndBiome(int biomeX, int biomeY, int biomeZ, MultiNoiseUtil.MultiNoiseSampler noise, CallbackInfoReturnable<RegistryEntry<Biome>> cir) {
cir.setReturnValue(overrides.pick(biomeX, biomeY, biomeZ, noise, cir.getReturnValue()));
}
}

View file

@ -11,8 +11,6 @@ mutable field net/minecraft/world/biome/source/BiomeSource indexedFeaturesSuppli
accessible field net/minecraft/world/biome/Biome weather Lnet/minecraft/world/biome/Biome$Weather;
accessible field net/minecraft/world/biome/Biome generationSettings Lnet/minecraft/world/biome/GenerationSettings;
accessible field net/minecraft/world/biome/Biome spawnSettings Lnet/minecraft/world/biome/SpawnSettings;
accessible field net/minecraft/world/biome/Biome category Lnet/minecraft/world/biome/Biome$Category;
mutable field net/minecraft/world/biome/Biome category Lnet/minecraft/world/biome/Biome$Category;
# Biome Weather
accessible field net/minecraft/world/biome/Biome$Weather precipitation Lnet/minecraft/world/biome/Biome$Precipitation;

View file

@ -5,6 +5,7 @@
"mixins": [
"modification.DynamicRegistryManagerImplMixin",
"modification.MinecraftServerMixin",
"MixinChunkGenerator",
"MixinMultiNoiseBiomeSource",
"MixinTheEndBiomeSource"
],

View file

@ -102,7 +102,7 @@ public class FabricBiomeTest implements ModInitializer {
BiomeSelectors.foundInOverworld(),
modification -> modification.getWeather().setDownfall(100))
.add(ModificationPhase.ADDITIONS,
BiomeSelectors.categories(Biome.Category.DESERT),
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()
@ -134,6 +134,6 @@ public class FabricBiomeTest implements ModInitializer {
private static Biome composeEndSpawnSettings(GenerationSettings.Builder builder) {
SpawnSettings.Builder builder2 = new SpawnSettings.Builder();
DefaultBiomeFeatures.addEndMobs(builder2);
return (new Biome.Builder()).precipitation(Biome.Precipitation.NONE).category(Biome.Category.THEEND).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();
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();
}
}

View file

@ -24,6 +24,7 @@ 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.class_7157;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
@ -42,8 +43,8 @@ public abstract class CommandManagerMixin {
*
* @reason Add commands before ambiguities are calculated.
*/
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;findAmbiguities(Lcom/mojang/brigadier/AmbiguityConsumer;)V"), method = "<init>")
private void fabric_addCommands(CommandManager.RegistrationEnvironment environment, CallbackInfo ci) {
@Inject(at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/CommandDispatcher;setConsumer(Lcom/mojang/brigadier/ResultConsumer;)V"), method = "<init>")
private void fabric_addCommands(CommandManager.RegistrationEnvironment environment, class_7157 arg, CallbackInfo ci) {
CommandRegistrationCallback.EVENT.invoker().register(this.dispatcher, environment == CommandManager.RegistrationEnvironment.DEDICATED);
}
}

View file

@ -65,7 +65,6 @@ import net.fabricmc.fabric.mixin.datagen.DynamicRegistryManagerAccessor;
public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
private final FabricDataGenerator fabricDataGenerator;
private final String path;
private final String name;
/**
* Construct a new {@link FabricTagProvider} with the default computed path.
@ -76,8 +75,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
* @param registry The backing registry for the Tag type.
* @param name The name used for {@link DataProvider#getName()}
*/
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String name) {
this(dataGenerator, registry, TagManagerLoader.getPath(registry.getKey()), name);
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry) {
this(dataGenerator, registry, TagManagerLoader.getPath(registry.getKey()));
}
/**
@ -88,14 +87,12 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
* @param dataGenerator The data generator instance
* @param registry The backing registry for the Tag type.
* @param path The directory name to write the tag file names. Example: "blocks" or "items"
* @param name The name used for {@link DataProvider#getName()}
*/
@SuppressWarnings({"unchecked", "rawtypes"})
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String path, String name) {
protected FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry, String path) {
super(dataGenerator, registry);
this.fabricDataGenerator = dataGenerator;
this.path = path.startsWith("tags/") ? path : "tags/" + path;
this.name = name;
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.");
@ -128,11 +125,6 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
generateTags();
}
@Override
public String getName() {
return name;
}
/**
* Extend this class to create {@link Block} tags in the "/blocks" tag directory.
*/
@ -226,8 +218,8 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
* @param name The name used for {@link DataProvider#getName()}
* @throws IllegalArgumentException if the registry is static registry
*/
protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey, String path, String name) {
super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(), path, name);
protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey, String path) {
super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(), path);
Preconditions.checkArgument(DynamicRegistryManagerAccessor.getInfos().containsKey(registryKey), "Only dynamic registries are supported in this tag provider.");
}
}

View file

@ -88,6 +88,7 @@ transitive-accessible method net/minecraft/data/server/RecipeProvider convertBet
transitive-accessible method net/minecraft/data/server/RecipeProvider getSmeltingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/RecipeProvider getBlastingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createStoneState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator method_42039 (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDeepslateState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator excludeFromSimpleItemModelGeneration (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerParentedItemModel (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;)V
@ -106,8 +107,8 @@ transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerMirrorable (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerRotatable (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createButtonBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator fillDoorVariantMap (Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;Lnet/minecraft/block/enums/DoubleBlockHalf;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDoorBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator fillDoorVariantMap (Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;Lnet/minecraft/block/enums/DoubleBlockHalf;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createDoorBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createFenceBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createWallBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createFenceGateBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;

View file

@ -87,7 +87,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
}
try {
new FabricTagProvider.DynamicRegistryTagProvider<>(dataGenerator, Registry.ITEM_KEY, "items", "Item Tags") {
new FabricTagProvider.DynamicRegistryTagProvider<>(dataGenerator, Registry.ITEM_KEY, "items") {
@Override
protected void generateTags() {
}
@ -164,7 +164,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
private static class TestBiomeTagProvider extends FabricTagProvider.DynamicRegistryTagProvider<Biome> {
private TestBiomeTagProvider(FabricDataGenerator dataGenerator) {
super(dataGenerator, Registry.BIOME_KEY, "biomes", "Biome Tags");
super(dataGenerator, Registry.BIOME_KEY, "biomes");
}
@Override

View file

@ -24,6 +24,7 @@ import java.util.concurrent.Executor;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.class_7138;
import net.minecraft.block.BlockState;
import net.minecraft.structure.StructureSet;
import net.minecraft.util.dynamic.RegistryOps;
@ -36,7 +37,6 @@ import net.minecraft.world.biome.Biome;
import net.minecraft.world.biome.BiomeKeys;
import net.minecraft.world.biome.source.BiomeAccess;
import net.minecraft.world.biome.source.FixedBiomeSource;
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.GenerationStep;
import net.minecraft.world.gen.StructureAccessor;
@ -46,11 +46,8 @@ import net.minecraft.world.gen.chunk.VerticalBlockSample;
public class VoidChunkGenerator extends ChunkGenerator {
public static final Codec<VoidChunkGenerator> CODEC = RecordCodecBuilder.create((instance) ->
method_41042(instance).and(
RegistryOps.createRegistryCodec(Registry.BIOME_KEY).forGetter((generator) -> generator.biomeRegistry)
)
.apply(instance, instance.stable(VoidChunkGenerator::new))
);
method_41042(instance).and(RegistryOps.createRegistryCodec(Registry.BIOME_KEY).forGetter((generator) -> generator.biomeRegistry))
.apply(instance, instance.stable(VoidChunkGenerator::new)));
private final Registry<Biome> biomeRegistry;
@ -65,22 +62,11 @@ public class VoidChunkGenerator extends ChunkGenerator {
}
@Override
public ChunkGenerator withSeed(long seed) {
return this;
public void carve(ChunkRegion chunkRegion, long l, class_7138 rng, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, GenerationStep.Carver carver) {
}
@Override
public MultiNoiseUtil.MultiNoiseSampler getMultiNoiseSampler() {
// Mirror what Vanilla does in the debug chunk generator
return MultiNoiseUtil.method_40443();
}
@Override
public void carve(ChunkRegion chunkRegion, long l, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk, GenerationStep.Carver carver) {
}
@Override
public void buildSurface(ChunkRegion region, StructureAccessor structureAccessor, Chunk chunk) {
public void buildSurface(ChunkRegion region, StructureAccessor structureAccessor, class_7138 rng, Chunk chunk) {
}
@Override
@ -93,7 +79,7 @@ public class VoidChunkGenerator extends ChunkGenerator {
}
@Override
public CompletableFuture<Chunk> populateNoise(Executor executor, Blender blender, StructureAccessor structureAccessor, Chunk chunk) {
public CompletableFuture<Chunk> populateNoise(Executor executor, Blender blender, class_7138 rng, StructureAccessor structureAccessor, Chunk chunk) {
return CompletableFuture.completedFuture(chunk);
}
@ -108,16 +94,16 @@ public class VoidChunkGenerator extends ChunkGenerator {
}
@Override
public int getHeight(int x, int z, Heightmap.Type heightmapType, HeightLimitView heightLimitView) {
public int getHeight(int x, int z, Heightmap.Type heightmapType, HeightLimitView heightLimitView, class_7138 rng) {
return 0;
}
@Override
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView heightLimitView) {
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView heightLimitView, class_7138 rng) {
return new VerticalBlockSample(0, new BlockState[0]);
}
@Override
public void getDebugHudText(List<String> list, BlockPos blockPos) {
public void getDebugHudText(List<String> list, class_7138 rng, BlockPos blockPos) {
}
}

View file

@ -23,6 +23,7 @@ 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.class_7204;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
@ -35,6 +36,7 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.TypedActionResult;
@ -44,7 +46,6 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameMode;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.AttackEntityCallback;
@ -61,9 +62,6 @@ public abstract class MixinClientPlayerInteractionManager {
@Shadow
private GameMode gameMode;
@Shadow
protected abstract void sendPlayerAction(PlayerActionC2SPacket.Action action, BlockPos pos, Direction direction);
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/world/GameMode;isCreative()Z", ordinal = 0), method = "attackBlock", cancellable = true)
public void attackBlock(BlockPos pos, Direction direction, CallbackInfoReturnable<Boolean> info) {
ActionResult result = AttackBlockCallback.EVENT.invoker().interact(client.player, client.world, Hand.MAIN_HAND, pos, direction);
@ -74,7 +72,7 @@ public abstract class MixinClientPlayerInteractionManager {
// We also need to let the server process the action if it's accepted.
if (result.isAccepted()) {
this.sendPlayerAction(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction);
method_41931(client.world, id -> new PlayerActionC2SPacket(PlayerActionC2SPacket.Action.START_DESTROY_BLOCK, pos, direction, id));
}
}
}
@ -93,13 +91,19 @@ public abstract class MixinClientPlayerInteractionManager {
}
}
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getStackInHand(Lnet/minecraft/util/Hand;)Lnet/minecraft/item/ItemStack;", ordinal = 0), method = "interactBlock", cancellable = true)
public void interactBlock(ClientPlayerEntity player, ClientWorld world, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> info) {
ActionResult result = UseBlockCallback.EVENT.invoker().interact(player, world, hand, blockHitResult);
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerInteractionManager;method_41931(Lnet/minecraft/client/world/ClientWorld;Lnet/minecraft/class_7204;)V"), method = "interactBlock", cancellable = true)
public void interactBlock(ClientPlayerEntity player, Hand hand, BlockHitResult blockHitResult, CallbackInfoReturnable<ActionResult> info) {
// hook interactBlock between the world border check and the actual block interaction to invoke the use block event first
// this needs to be in interactBlock to avoid sending a packet in line with the event javadoc
if (player.isSpectator()) return; // vanilla spectator check happens later, repeat it before the event to avoid false invocations
ActionResult result = UseBlockCallback.EVENT.invoker().interact(player, player.world, hand, blockHitResult);
if (result != ActionResult.PASS) {
if (result == ActionResult.SUCCESS) {
this.networkHandler.sendPacket(new PlayerInteractBlockC2SPacket(hand, blockHitResult));
// send interaction packet to the server with a new sequentially assigned id
method_41931(player.clientWorld, id -> new PlayerInteractBlockC2SPacket(hand, blockHitResult, id));
}
info.setReturnValue(result);
@ -107,12 +111,17 @@ public abstract class MixinClientPlayerInteractionManager {
}
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayNetworkHandler;sendPacket(Lnet/minecraft/network/Packet;)V", ordinal = 0), method = "interactItem", cancellable = true)
public void interactItem(PlayerEntity player, World world, Hand hand, CallbackInfoReturnable<ActionResult> info) {
TypedActionResult<ItemStack> result = UseItemCallback.EVENT.invoker().interact(player, world, hand);
public void interactItem(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> info) {
// hook interactBlock between the spectator check and sending the first packet to invoke the use item event first
// this needs to be in interactBlock to avoid sending a packet in line with the event javadoc
TypedActionResult<ItemStack> result = UseItemCallback.EVENT.invoker().interact(player, player.world, hand);
if (result.getResult() != ActionResult.PASS) {
if (result.getResult() == ActionResult.SUCCESS) {
this.networkHandler.sendPacket(new PlayerInteractItemC2SPacket(hand));
// send the move packet like vanilla to ensure the position+view vectors are accurate
networkHandler.sendPacket(new PlayerMoveC2SPacket.Full(player.getX(), player.getY(), player.getZ(), player.getYaw(), player.getPitch(), player.isOnGround()));
// send interaction packet to the server with a new sequentially assigned id
method_41931((ClientWorld) player.world, id -> new PlayerInteractItemC2SPacket(hand, id));
}
info.setReturnValue(result.getResult());
@ -145,4 +154,7 @@ public abstract class MixinClientPlayerInteractionManager {
info.setReturnValue(result);
}
}
@Shadow
public abstract void method_41931(ClientWorld clientWorld, class_7204 supplier);
}

View file

@ -27,13 +27,13 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
@ -44,9 +44,9 @@ import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseItemCallback;
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
@Mixin(ServerPlayerInteractionManager.class)
public class MixinServerPlayerInteractionManager {
@ -56,7 +56,7 @@ public class MixinServerPlayerInteractionManager {
public ServerPlayerEntity player;
@Inject(at = @At("HEAD"), method = "processBlockBreakingAction", cancellable = true)
public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int i, CallbackInfo info) {
public void startBlockBreak(BlockPos pos, PlayerActionC2SPacket.Action playerAction, Direction direction, int worldHeight, int i, CallbackInfo info) {
if (playerAction != PlayerActionC2SPacket.Action.START_DESTROY_BLOCK) return;
ActionResult result = AttackBlockCallback.EVENT.invoker().interact(player, world, Hand.MAIN_HAND, pos, direction);

View file

@ -21,7 +21,7 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
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.SharedConstants;
import net.minecraft.command.argument.ArgumentTypes;
@ -29,20 +29,21 @@ import net.minecraft.command.argument.TestClassArgumentType;
import net.minecraft.command.argument.TestFunctionArgumentType;
import net.minecraft.command.argument.serialize.ArgumentSerializer;
import net.minecraft.command.argument.serialize.ConstantArgumentSerializer;
import net.minecraft.util.registry.Registry;
@Mixin(ArgumentTypes.class)
public abstract class ArgumentTypesMixin {
@Shadow
public static <T extends ArgumentType<?>> void register(String id, Class<T> argClass, ArgumentSerializer<T> serializer) {
private static <A extends ArgumentType<?>, T extends ArgumentSerializer.class_7217<A>> ArgumentSerializer<A, T> register(Registry<ArgumentSerializer<?, ?>> registry, String string, Class<? extends A> clazz, ArgumentSerializer<A, T> argumentSerializer) {
throw new AssertionError("Nope.");
}
@Inject(method = "register()V", at = @At("RETURN"))
private static void register(CallbackInfo ci) {
@Inject(method = "register(Lnet/minecraft/util/registry/Registry;)Lnet/minecraft/command/argument/serialize/ArgumentSerializer;", at = @At("RETURN"))
private static void register(Registry<ArgumentSerializer<?, ?>> registry, CallbackInfoReturnable<ArgumentSerializer<?, ?>> ci) {
// Registered by vanilla when isDevelopment is enabled.
if (!SharedConstants.isDevelopment) {
register("test_argument", TestFunctionArgumentType.class, new ConstantArgumentSerializer<>(TestFunctionArgumentType::testFunction));
register("test_class", TestClassArgumentType.class, new ConstantArgumentSerializer<>(TestClassArgumentType::testClass));
register(registry, "test_argument", TestFunctionArgumentType.class, ConstantArgumentSerializer.method_41999(TestFunctionArgumentType::testFunction));
register(registry, "test_class", TestClassArgumentType.class, ConstantArgumentSerializer.method_41999(TestClassArgumentType::testClass));
}
}
}

View file

@ -16,15 +16,16 @@
package net.fabricmc.fabric.mixin.gametest;
import com.mojang.brigadier.CommandDispatcher;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.SharedConstants;
import net.minecraft.class_7157;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.command.TestCommand;
@ -36,7 +37,7 @@ public abstract class CommandManagerMixin {
private CommandDispatcher<ServerCommandSource> dispatcher;
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/command/WorldBorderCommand;register(Lcom/mojang/brigadier/CommandDispatcher;)V", shift = At.Shift.AFTER))
private void construct(CommandManager.RegistrationEnvironment environment, CallbackInfo info) {
private void construct(CommandManager.RegistrationEnvironment environment, class_7157 arg, CallbackInfo info) {
// Registered by vanilla when isDevelopment is enabled.
if (!SharedConstants.isDevelopment) {
TestCommand.register(this.dispatcher);

View file

@ -26,8 +26,8 @@ import org.slf4j.LoggerFactory;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.tag.TagKey;
import net.minecraft.tag.BlockTags;
import net.minecraft.tag.TagKey;
import net.fabricmc.yarn.constants.MiningLevels;
@ -42,7 +42,7 @@ public final class MiningLevelManagerImpl {
private static final ThreadLocal<Reference2IntMap<BlockState>> CACHE = ThreadLocal.withInitial(Reference2IntOpenHashMap::new);
public static int getRequiredMiningLevel(BlockState state) {
return CACHE.get().computeIntIfAbsent(state, s -> {
return CACHE.get().computeIfAbsent(state, s -> {
int miningLevel = MiningLevels.HAND;
// Handle #fabric:needs_tool_level_N

View file

@ -75,7 +75,7 @@ public abstract class GroupResourcePack implements ResourcePack {
}
@Override
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
List<ModResourcePack> packs = this.namespacedPacks.get(namespace);
if (packs == null) {
@ -86,7 +86,7 @@ public abstract class GroupResourcePack implements ResourcePack {
for (int i = packs.size() - 1; i >= 0; i--) {
ResourcePack pack = packs.get(i);
Collection<Identifier> modResources = pack.findResources(type, namespace, prefix, maxDepth, pathFilter);
Collection<Identifier> modResources = pack.findResources(type, namespace, prefix, predicate);
resources.addAll(modResources);
}

View file

@ -36,8 +36,8 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.minecraft.resource.AbstractFileResourcePack;
import net.minecraft.resource.ResourceType;
@ -209,7 +209,7 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
}
@Override
public Collection<Identifier> findResources(ResourceType type, String namespace, String path, int depth, Predicate<String> predicate) {
public Collection<Identifier> findResources(ResourceType type, String namespace, String path, Predicate<Identifier> predicate) {
if (!namespaces.getOrDefault(type, Collections.emptySet()).contains(namespace)) {
return Collections.emptyList();
}
@ -227,14 +227,13 @@ public class ModNioResourcePack extends AbstractFileResourcePack implements ModR
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
String fileName = file.getFileName().toString();
if (fileName.endsWith(".mcmeta")) return FileVisitResult.CONTINUE;
if (!fileName.endsWith(".mcmeta")
&& predicate.test(fileName)) {
try {
ids.add(new Identifier(namespace, nsPath.relativize(file).toString().replace(separator, "/")));
} catch (InvalidIdentifierException e) {
LOGGER.error(e.getMessage());
}
try {
Identifier id = new Identifier(namespace, nsPath.relativize(file).toString().replace(separator, "/"));
if (predicate.test(id)) ids.add(id);
} catch (InvalidIdentifierException e) {
LOGGER.error(e.getMessage());
}
return FileVisitResult.CONTINUE;

View file

@ -71,10 +71,10 @@ public class ProgrammerArtResourcePack extends GroupResourcePack {
}
@Override
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
Set<Identifier> resources = new HashSet<>(this.originalResourcePack.findResources(type, namespace, prefix, maxDepth, pathFilter));
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
Set<Identifier> resources = new HashSet<>(this.originalResourcePack.findResources(type, namespace, prefix, predicate));
resources.addAll(super.findResources(type, namespace, prefix, maxDepth, pathFilter));
resources.addAll(super.findResources(type, namespace, prefix, predicate));
return resources;
}

View file

@ -83,8 +83,8 @@ public abstract class DefaultResourcePackMixin {
* @reason Gets rid of classpath scanning.
*/
@Overwrite
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, int maxDepth, Predicate<String> pathFilter) {
return fabric_mcJarPack.findResources(type, namespace, prefix, maxDepth, pathFilter);
public Collection<Identifier> findResources(ResourceType type, String namespace, String prefix, Predicate<Identifier> predicate) {
return fabric_mcJarPack.findResources(type, namespace, prefix, predicate);
}
/**

View file

@ -26,6 +26,7 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.gui.screen.world.CreateWorldScreen;
@ -44,6 +45,14 @@ public class CreateWorldScreenMixin {
@Shadow
private ResourcePackManager packManager;
@ModifyVariable(method = "create(Lnet/minecraft/client/MinecraftClient;Lnet/minecraft/client/gui/screen/Screen;)V",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/world/CreateWorldScreen;method_41849(Lnet/minecraft/resource/ResourcePackManager;Lnet/minecraft/resource/DataPackSettings;)Lnet/minecraft/class_7237$FunctionLoaderConfig;"))
private static ResourcePackManager onCreateResManagerInit(ResourcePackManager manager) {
// Add mod data packs to the initial res pack manager so they are active even if the user doesn't use custom data packs
((ResourcePackManagerAccessor) manager).getProviders().add(new ModResourcePackCreator(ResourceType.SERVER_DATA));
return manager;
}
@Inject(method = "getScannedPack", at = @At(value = "INVOKE", target = "Lnet/minecraft/resource/ResourcePackManager;scanPacks()V", shift = At.Shift.BEFORE))
private void onScanPacks(CallbackInfoReturnable<Pair<File, ResourcePackManager>> cir) {
// Allow to display built-in data packs in the data pack selection screen at world creation.

View file

@ -127,7 +127,7 @@ abstract class MouseMixin {
}
// Apply same calculations to horizontal scroll as vertical scroll amount has
this.horizontalScrollAmount = this.client.options.discreteMouseScroll ? Math.signum(horizontal) : horizontal * this.client.options.mouseWheelSensitivity;
this.horizontalScrollAmount = this.client.options.discreteMouseScroll ? Math.signum(horizontal) : horizontal * this.client.options.method_41806().method_41753();
if (!ScreenMouseEvents.allowMouseScroll(this.currentScreen).invoker().allowMouseScroll(this.currentScreen, mouseX, mouseY, this.horizontalScrollAmount, verticalAmount)) {
this.currentScreen = null;

View file

@ -1,9 +1,9 @@
org.gradle.jvmargs=-Xmx2560M
version=0.48.0
minecraft_version=1.18.2
yarn_version=+build.1
loader_version=0.13.2
version=0.49.0
minecraft_version=22w11a
yarn_version=+build.2
loader_version=0.13.3
prerelease=false

View file

@ -18,7 +18,7 @@
"depends": {
"fabricloader": ">=0.13.2",
"java": ">=17",
"minecraft": "~1.18.2-alpha.22.5.a"
"minecraft": "~1.19-alpha.22.11.a"
},
"description": "Core API module providing key hooks and intercompatibility features."
}