22w42a 🐫 (#2599)

Co-authored-by: shartte <shartte@users.noreply.github.com>
Co-authored-by: Juuz <6596629+Juuxel@users.noreply.github.com>
This commit is contained in:
modmuss50 2022-10-22 20:38:33 +01:00 committed by GitHub
parent c9f64f5a6e
commit 75e98211bd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
177 changed files with 2904 additions and 1955 deletions

View file

@ -9,7 +9,7 @@ plugins {
id "eclipse" id "eclipse"
id "idea" id "idea"
id "maven-publish" id "maven-publish"
id "fabric-loom" version "1.0.7" apply false id "fabric-loom" version "1.0.11" apply false
id "com.diffplug.spotless" version "6.11.0" id "com.diffplug.spotless" version "6.11.0"
id "org.ajoberstar.grgit" version "3.1.0" id "org.ajoberstar.grgit" version "3.1.0"
id "com.matthewprenger.cursegradle" version "1.4.0" id "com.matthewprenger.cursegradle" version "1.4.0"
@ -286,6 +286,11 @@ remapTestmodJar {
apply from: "gradle/module-validation.gradle" apply from: "gradle/module-validation.gradle"
apply from: "gradle/module-versioning.gradle" apply from: "gradle/module-versioning.gradle"
loom {
// Required as the item-group API uses access widened classes in its API, without this the javadoc generation fails.
accessWidenerPath = file("fabric-item-group-api-v1/src/main/resources/fabric-item-group-api-v1.accesswidener")
}
javadoc { javadoc {
options { options {
source = "17" source = "17"
@ -318,7 +323,7 @@ javadoc {
classpath = files(sourceSets.main.compileClasspath, sourceSets.client.compileClasspath) classpath = files(sourceSets.main.compileClasspath, sourceSets.client.compileClasspath)
include("**/api/**") include("**/api/**")
failOnError false failOnError true
} }
task javadocJar(type: Jar) { task javadocJar(type: Jar) {
@ -511,7 +516,7 @@ curseforge {
id = "306612" id = "306612"
changelog = ENV.CHANGELOG ?: "No changelog provided" changelog = ENV.CHANGELOG ?: "No changelog provided"
releaseType = project.prerelease == "true" ? "beta" : "release" releaseType = project.prerelease == "true" ? "beta" : "release"
addGameVersion "1.19.2" addGameVersion "1.19.3"
addGameVersion "Fabric" addGameVersion "Fabric"
mainArtifact(signingEnabled ? signRemapJar.output : remapJar) { mainArtifact(signingEnabled ? signRemapJar.output : remapJar) {

View file

@ -194,7 +194,7 @@
- largely unconstained trailing subpackages - largely unconstained trailing subpackages
--> -->
<property name="format" <property name="format"
value="^net\.fabricmc\.fabric\.(api(?!\.common\.)(\.client|\.server|)(\.(?!client\.|server\.)[a-z]+([a-rt-z]|ss))+\.v[1-9][0-9]*|(impl|mixin|test)(?!\.common\.)(\.client|\.server|)(\.(?!client\.|server\.)[a-z]+([a-rt-z]|ss))+(\.v[1-9][0-9]*)?|api\.(event|util|biomes\.v1|registry|client\.screen|container|block|entity|client\.itemgroup|client\.keybinding|tag|tools|client\.model|network|server|client\.render|resource|client\.texture))(|\.[a-z]+(\.[a-z0-9]+)*)$"/> value="^net\.fabricmc\.fabric\.(api(?!\.common\.)(\.client|\.server|)(\.(?!client\.|server\.)[a-z]+([a-rt-z]|ss))+\.v[1-9][0-9]*|(impl|mixin|test)(?!\.common\.)(\.client|\.server|)(\.(?!client\.|server\.)[a-z]+([a-rt-z]|ss))+(\.v[1-9][0-9]*)?|api\.(event|util|biomes\.v1|registry|client\.screen|container|block|entity|client\.keybinding|tag|tools|client\.model|network|server|client\.render|resource|client\.texture))(|\.[a-z]+(\.[a-z0-9]+)*)$"/>
</module> </module>
<!--<module name="InvalidJavadocPosition"/>--> <!--<module name="InvalidJavadocPosition"/>-->

View file

@ -22,7 +22,6 @@ import net.minecraft.block.Material;
import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
@ -43,17 +42,17 @@ public class FabricApiLookupTest implements ModInitializer {
// Chute - Block without model that transfers item from the container above to the container below. // Chute - Block without model that transfers item from the container above to the container below.
// It's meant to work with unsided containers: chests, dispensers, droppers and hoppers. // It's meant to work with unsided containers: chests, dispensers, droppers and hoppers.
public static final ChuteBlock CHUTE_BLOCK = new ChuteBlock(FabricBlockSettings.of(Material.METAL)); public static final ChuteBlock CHUTE_BLOCK = new ChuteBlock(FabricBlockSettings.of(Material.METAL));
public static final BlockItem CHUTE_ITEM = new BlockItem(CHUTE_BLOCK, new Item.Settings().group(ItemGroup.MISC)); public static final BlockItem CHUTE_ITEM = new BlockItem(CHUTE_BLOCK, new Item.Settings());
public static BlockEntityType<ChuteBlockEntity> CHUTE_BLOCK_ENTITY_TYPE; public static BlockEntityType<ChuteBlockEntity> CHUTE_BLOCK_ENTITY_TYPE;
// Cobble gen - Block without model that can generate infinite cobblestone when placed above a chute. // Cobble gen - Block without model that can generate infinite cobblestone when placed above a chute.
// It's meant to test BlockApiLookup#registerSelf. // It's meant to test BlockApiLookup#registerSelf.
public static final CobbleGenBlock COBBLE_GEN_BLOCK = new CobbleGenBlock(FabricBlockSettings.of(Material.METAL)); public static final CobbleGenBlock COBBLE_GEN_BLOCK = new CobbleGenBlock(FabricBlockSettings.of(Material.METAL));
public static final BlockItem COBBLE_GEN_ITEM = new BlockItem(COBBLE_GEN_BLOCK, new Item.Settings().group(ItemGroup.MISC)); public static final BlockItem COBBLE_GEN_ITEM = new BlockItem(COBBLE_GEN_BLOCK, new Item.Settings());
public static BlockEntityType<CobbleGenBlockEntity> COBBLE_GEN_BLOCK_ENTITY_TYPE; public static BlockEntityType<CobbleGenBlockEntity> COBBLE_GEN_BLOCK_ENTITY_TYPE;
// Testing for item api lookups is done in the `item` package. // Testing for item api lookups is done in the `item` package.
public static final InspectorBlock INSPECTOR_BLOCK = new InspectorBlock(FabricBlockSettings.of(Material.METAL)); public static final InspectorBlock INSPECTOR_BLOCK = new InspectorBlock(FabricBlockSettings.of(Material.METAL));
public static final BlockItem INSPECTOR_ITEM = new BlockItem(INSPECTOR_BLOCK, new Item.Settings().group(ItemGroup.MISC)); public static final BlockItem INSPECTOR_ITEM = new BlockItem(INSPECTOR_BLOCK, new Item.Settings());
@Override @Override
public void onInitialize() { public void onInitialize() {

View file

@ -17,7 +17,6 @@
package net.fabricmc.fabric.test.lookup.item; package net.fabricmc.fabric.test.lookup.item;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.fabricmc.fabric.test.lookup.api.Inspectable; import net.fabricmc.fabric.test.lookup.api.Inspectable;
@ -26,7 +25,7 @@ public class InspectableItem extends Item implements Inspectable {
private final String inspectionResult; private final String inspectionResult;
public InspectableItem(String inspectionResult) { public InspectableItem(String inspectionResult) {
super(new Settings().group(ItemGroup.MISC)); super(new Settings());
this.inspectionResult = inspectionResult; this.inspectionResult = inspectionResult;
} }

1
fabric-biome-api-v1/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/src/testmod/generated/.cache

View file

@ -7,5 +7,36 @@ loom {
testDependencies(project, [ testDependencies(project, [
':fabric-api-base', ':fabric-api-base',
':fabric-resource-loader-v0' ':fabric-resource-loader-v0',
':fabric-registry-sync-v0',
':fabric-data-generation-api-v1'
]) ])
sourceSets {
testmod {
resources {
srcDirs += [
'src/testmod/generated'
]
}
}
}
loom {
runs {
datagen {
inherit testmodServer
name "Data Generation"
vmArg "-Dfabric-api.datagen"
vmArg "-Dfabric-api.datagen.output-dir=${file("src/testmod/generated")}"
vmArg "-Dfabric-api.datagen.strict-validation"
ideConfigGenerated = true
runDir "build/datagen"
}
}
}
// Ensure the worldgen JSONs are re-created to ensure the data-gen still works
test.dependsOn runDatagen
runTestmodClient.dependsOn runDatagen

View file

@ -40,6 +40,7 @@ import net.minecraft.sound.BiomeMoodSound;
import net.minecraft.sound.MusicSound; import net.minecraft.sound.MusicSound;
import net.minecraft.sound.SoundEvent; import net.minecraft.sound.SoundEvent;
import net.minecraft.util.collection.Pool; import net.minecraft.util.collection.Pool;
import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.DynamicRegistryManager; import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryEntry; import net.minecraft.util.registry.RegistryEntry;
@ -60,16 +61,14 @@ import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
@ApiStatus.Internal @ApiStatus.Internal
public class BiomeModificationContextImpl implements BiomeModificationContext { public class BiomeModificationContextImpl implements BiomeModificationContext {
private final DynamicRegistryManager registries; private final DynamicRegistryManager registries;
private final RegistryKey<Biome> biomeKey;
private final Biome biome; private final Biome biome;
private final WeatherContext weather; private final WeatherContext weather;
private final EffectsContext effects; private final EffectsContext effects;
private final GenerationSettingsContextImpl generationSettings; private final GenerationSettingsContextImpl generationSettings;
private final SpawnSettingsContextImpl spawnSettings; private final SpawnSettingsContextImpl spawnSettings;
public BiomeModificationContextImpl(DynamicRegistryManager registries, RegistryKey<Biome> biomeKey, Biome biome) { public BiomeModificationContextImpl(DynamicRegistryManager registries, Biome biome) {
this.registries = registries; this.registries = registries;
this.biomeKey = biomeKey;
this.biome = biome; this.biome = biome;
this.weather = new WeatherContextImpl(); this.weather = new WeatherContextImpl();
this.effects = new EffectsContextImpl(); this.effects = new EffectsContextImpl();
@ -257,7 +256,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
@Override @Override
public boolean removeFeature(GenerationStep.Feature step, RegistryKey<PlacedFeature> placedFeatureKey) { public boolean removeFeature(GenerationStep.Feature step, RegistryKey<PlacedFeature> placedFeatureKey) {
PlacedFeature configuredFeature = features.getOrThrow(placedFeatureKey); PlacedFeature placedFeature = getEntry(features, placedFeatureKey).value();
int stepIndex = step.ordinal(); int stepIndex = step.ordinal();
List<RegistryEntryList<PlacedFeature>> featureSteps = generationSettings.features; List<RegistryEntryList<PlacedFeature>> featureSteps = generationSettings.features;
@ -269,7 +268,7 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
RegistryEntryList<PlacedFeature> featuresInStep = featureSteps.get(stepIndex); RegistryEntryList<PlacedFeature> featuresInStep = featureSteps.get(stepIndex);
List<RegistryEntry<PlacedFeature>> features = new ArrayList<>(featuresInStep.stream().toList()); List<RegistryEntry<PlacedFeature>> features = new ArrayList<>(featuresInStep.stream().toList());
if (features.removeIf(feature -> feature.value() == configuredFeature)) { if (features.removeIf(feature -> feature.value() == placedFeature)) {
featureSteps.set(stepIndex, RegistryEntryList.of(features)); featureSteps.set(stepIndex, RegistryEntryList.of(features));
rebuildFlowerFeatures = true; rebuildFlowerFeatures = true;
@ -289,21 +288,21 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
featureSteps.add(RegistryEntryList.of(Collections.emptyList())); featureSteps.add(RegistryEntryList.of(Collections.emptyList()));
} }
featureSteps.set(index, plus(featureSteps.get(index), features.getEntry(entry).orElseThrow())); featureSteps.set(index, plus(featureSteps.get(index), getEntry(features, entry)));
// Ensure the list of flower features is up to date // Ensure the list of flower features is up-to-date
rebuildFlowerFeatures = true; rebuildFlowerFeatures = true;
} }
@Override @Override
public void addCarver(GenerationStep.Carver step, RegistryKey<ConfiguredCarver<?>> entry) { public void addCarver(GenerationStep.Carver step, RegistryKey<ConfiguredCarver<?>> entry) {
// We do not need to delay evaluation of this since the registries are already fully built // We do not need to delay evaluation of this since the registries are already fully built
generationSettings.carvers.put(step, plus(generationSettings.carvers.get(step), carvers.getEntry(entry).orElseThrow())); generationSettings.carvers.put(step, plus(generationSettings.carvers.get(step), getEntry(carvers, entry)));
} }
@Override @Override
public boolean removeCarver(GenerationStep.Carver step, RegistryKey<ConfiguredCarver<?>> configuredCarverKey) { public boolean removeCarver(GenerationStep.Carver step, RegistryKey<ConfiguredCarver<?>> configuredCarverKey) {
ConfiguredCarver<?> carver = carvers.getOrThrow(configuredCarverKey); ConfiguredCarver<?> carver = getEntry(carvers, configuredCarverKey).value();
List<RegistryEntry<ConfiguredCarver<?>>> genCarvers = new ArrayList<>(generationSettings.carvers.get(step).stream().toList()); List<RegistryEntry<ConfiguredCarver<?>>> genCarvers = new ArrayList<>(generationSettings.carvers.get(step).stream().toList());
if (genCarvers.removeIf(entry -> entry.value() == carver)) { if (genCarvers.removeIf(entry -> entry.value() == carver)) {
@ -321,6 +320,33 @@ public class BiomeModificationContextImpl implements BiomeModificationContext {
} }
} }
/**
* Gets an entry from the given registry, assuming it's a registry loaded from data packs.
* Gives more helpful error messages if an entry is missing by checking if the modder
* forgot to data-gen the JSONs corresponding to their built-in objects.
*/
private static <T> RegistryEntry.Reference<T> getEntry(Registry<T> registry, RegistryKey<T> key) {
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
throw new IllegalArgumentException("Couldn't find registry entry for " + key);
}
return entry;
}
private class SpawnSettingsContextImpl implements SpawnSettingsContext { private class SpawnSettingsContextImpl implements SpawnSettingsContext {
private final SpawnSettings spawnSettings = biome.getSpawnSettings(); private final SpawnSettings spawnSettings = biome.getSpawnSettings();
private final EnumMap<SpawnGroup, List<SpawnSettings.SpawnEntry>> fabricSpawners = new EnumMap<>(SpawnGroup.class); private final EnumMap<SpawnGroup, List<SpawnSettings.SpawnEntry>> fabricSpawners = new EnumMap<>(SpawnGroup.class);

View file

@ -36,7 +36,6 @@ import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.RegistryKey;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
import net.minecraft.world.level.LevelProperties;
import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext; import net.fabricmc.fabric.api.biome.v1.BiomeModificationContext;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
@ -102,8 +101,7 @@ public class BiomeModificationImpl {
return modifiers; return modifiers;
} }
@SuppressWarnings("ConstantConditions") public void finalizeWorldGen(DynamicRegistryManager impl) {
public void finalizeWorldGen(DynamicRegistryManager impl, LevelProperties levelProperties) {
Stopwatch sw = Stopwatch.createStarted(); Stopwatch sw = Stopwatch.createStarted();
// Now that we apply biome modifications inside the MinecraftServer constructor, we should only ever do // Now that we apply biome modifications inside the MinecraftServer constructor, we should only ever do
@ -134,7 +132,7 @@ public class BiomeModificationImpl {
// Make a copy of the biome to allow selection contexts to see it unmodified, // Make a copy of the biome to allow selection contexts to see it unmodified,
// But do so only once it's known anything wants to modify the biome at all // But do so only once it's known anything wants to modify the biome at all
BiomeSelectionContext context = new BiomeSelectionContextImpl(impl, levelProperties, key, biome); BiomeSelectionContext context = new BiomeSelectionContextImpl(impl, key, biome);
BiomeModificationContextImpl modificationContext = null; BiomeModificationContextImpl modificationContext = null;
for (ModifierRecord modifier : sortedModifiers) { for (ModifierRecord modifier : sortedModifiers) {
@ -144,7 +142,7 @@ public class BiomeModificationImpl {
// Create the copy only if at least one modifier applies, since it's pretty costly // Create the copy only if at least one modifier applies, since it's pretty costly
if (modificationContext == null) { if (modificationContext == null) {
biomesChanged++; biomesChanged++;
modificationContext = new BiomeModificationContextImpl(impl, key, biome); modificationContext = new BiomeModificationContextImpl(impl, biome);
} }
modifier.apply(context, modificationContext); modifier.apply(context, modificationContext);

View file

@ -30,21 +30,18 @@ import net.minecraft.world.dimension.DimensionOptions;
import net.minecraft.world.gen.feature.ConfiguredFeature; import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.PlacedFeature; import net.minecraft.world.gen.feature.PlacedFeature;
import net.minecraft.world.gen.structure.Structure; import net.minecraft.world.gen.structure.Structure;
import net.minecraft.world.level.LevelProperties;
import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext; import net.fabricmc.fabric.api.biome.v1.BiomeSelectionContext;
@ApiStatus.Internal @ApiStatus.Internal
public class BiomeSelectionContextImpl implements BiomeSelectionContext { public class BiomeSelectionContextImpl implements BiomeSelectionContext {
private final DynamicRegistryManager dynamicRegistries; private final DynamicRegistryManager dynamicRegistries;
private final LevelProperties levelProperties;
private final RegistryKey<Biome> key; private final RegistryKey<Biome> key;
private final Biome biome; private final Biome biome;
private final RegistryEntry<Biome> entry; private final RegistryEntry<Biome> entry;
public BiomeSelectionContextImpl(DynamicRegistryManager dynamicRegistries, LevelProperties levelProperties, RegistryKey<Biome> key, Biome biome) { public BiomeSelectionContextImpl(DynamicRegistryManager dynamicRegistries, RegistryKey<Biome> key, Biome biome) {
this.dynamicRegistries = dynamicRegistries; this.dynamicRegistries = dynamicRegistries;
this.levelProperties = levelProperties;
this.key = key; this.key = key;
this.biome = biome; this.biome = biome;
this.entry = dynamicRegistries.get(Registry.BIOME_KEY).getEntry(this.key).orElseThrow(); this.entry = dynamicRegistries.get(Registry.BIOME_KEY).getEntry(this.key).orElseThrow();
@ -96,13 +93,13 @@ public class BiomeSelectionContextImpl implements BiomeSelectionContext {
@Override @Override
public boolean canGenerateIn(RegistryKey<DimensionOptions> dimensionKey) { public boolean canGenerateIn(RegistryKey<DimensionOptions> dimensionKey) {
DimensionOptions dimension = levelProperties.getGeneratorOptions().getDimensions().get(dimensionKey); DimensionOptions dimension = dynamicRegistries.get(Registry.DIMENSION_KEY).get(dimensionKey);
if (dimension == null) { if (dimension == null) {
return false; return false;
} }
return dimension.getChunkGenerator().getBiomeSource().getBiomes().stream().anyMatch(entry -> entry.value() == biome); return dimension.chunkGenerator().getBiomeSource().getBiomes().stream().anyMatch(entry -> entry.value() == biome);
} }
@Override @Override

View file

@ -16,7 +16,6 @@
package net.fabricmc.fabric.mixin.biome; package net.fabricmc.fabric.mixin.biome;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -27,25 +26,24 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.WorldGenerationProgressListener; import net.minecraft.server.WorldGenerationProgressListener;
import net.minecraft.util.registry.DynamicRegistryManager; import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.world.SaveProperties; import net.minecraft.world.dimension.DimensionOptions;
import net.fabricmc.fabric.impl.biome.NetherBiomeData; import net.fabricmc.fabric.impl.biome.NetherBiomeData;
@Mixin(MinecraftServer.class) @Mixin(MinecraftServer.class)
public class MinecraftServerMixin { public class MinecraftServerMixin {
@Shadow @Shadow
@Final private DynamicRegistryManager.Immutable getRegistryManager() {
protected SaveProperties saveProperties; throw new AssertionError();
}
@Shadow
@Final
private DynamicRegistryManager.Immutable registryManager;
@Inject(method = "createWorlds", at = @At("HEAD")) @Inject(method = "createWorlds", at = @At("HEAD"))
private void addNetherBiomes(WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo ci) { private void addNetherBiomes(WorldGenerationProgressListener worldGenerationProgressListener, CallbackInfo ci) {
// This is the last point where we can safely modify worldgen related things // This is the last point where we can safely modify worldgen related things
// plus, this is server-side only, and DRM is easily accessible // plus, this is server-side only, and DRM is easily accessible
// please blame Mojang for using dynamic registry // please blame Mojang for using dynamic registry
this.saveProperties.getGeneratorOptions().getDimensions().stream().forEach(dimensionOptions -> NetherBiomeData.modifyBiomeSource(this.registryManager.get(Registry.BIOME_KEY), dimensionOptions.getChunkGenerator().getBiomeSource())); Registry<DimensionOptions> registry = getRegistryManager().get(Registry.DIMENSION_KEY);
registry.stream().forEach(dimensionOptions -> NetherBiomeData.modifyBiomeSource(getRegistryManager().get(Registry.BIOME_KEY), dimensionOptions.chunkGenerator().getBiomeSource()));
} }
} }

View file

@ -45,6 +45,6 @@ public abstract class MinecraftServerMixin {
throw new RuntimeException("Incompatible SaveProperties passed to MinecraftServer: " + saveProperties); throw new RuntimeException("Incompatible SaveProperties passed to MinecraftServer: " + saveProperties);
} }
BiomeModificationImpl.INSTANCE.finalizeWorldGen(getRegistryManager(), levelProperties); BiomeModificationImpl.INSTANCE.finalizeWorldGen(getRegistryManager());
} }
} }

View file

@ -0,0 +1,200 @@
{
"carvers": {
"air": [
"minecraft:cave",
"minecraft:cave_extra_underground",
"minecraft:canyon"
]
},
"downfall": 0.4,
"effects": {
"fog_color": 12638463,
"mood_sound": {
"block_search_extent": 8,
"offset": 2.0,
"sound": "minecraft:ambient.cave",
"tick_delay": 6000
},
"sky_color": 7907327,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [
[],
[
"minecraft:lake_lava_underground",
"minecraft:lake_lava_surface"
],
[
"minecraft:amethyst_geode"
],
[
"minecraft:monster_room",
"minecraft:monster_room_deep"
],
[],
[],
[
"minecraft:ore_dirt",
"minecraft:ore_gravel",
"minecraft:ore_granite_upper",
"minecraft:ore_granite_lower",
"minecraft:ore_diorite_upper",
"minecraft:ore_diorite_lower",
"minecraft:ore_andesite_upper",
"minecraft:ore_andesite_lower",
"minecraft:ore_tuff",
"minecraft:ore_coal_upper",
"minecraft:ore_coal_lower",
"minecraft:ore_iron_upper",
"minecraft:ore_iron_middle",
"minecraft:ore_iron_small",
"minecraft:ore_gold",
"minecraft:ore_gold_lower",
"minecraft:ore_redstone",
"minecraft:ore_redstone_lower",
"minecraft:ore_diamond",
"minecraft:ore_diamond_large",
"minecraft:ore_diamond_buried",
"minecraft:ore_lapis",
"minecraft:ore_lapis_buried",
"minecraft:ore_copper",
"minecraft:underwater_magma",
"minecraft:disk_sand",
"minecraft:disk_clay",
"minecraft:disk_gravel"
],
[],
[
"minecraft:spring_water",
"minecraft:spring_lava"
],
[
"minecraft:glow_lichen",
"minecraft:patch_tall_grass_2",
"minecraft:trees_plains",
"minecraft:flower_plains",
"minecraft:patch_grass_plain",
"minecraft:brown_mushroom_normal",
"minecraft:red_mushroom_normal",
"minecraft:patch_sugar_cane",
"minecraft:patch_pumpkin"
],
[
"minecraft:freeze_top_layer"
]
],
"precipitation": "rain",
"spawn_costs": {},
"spawners": {
"ambient": [
{
"type": "minecraft:bat",
"maxCount": 8,
"minCount": 8,
"weight": 10
}
],
"axolotls": [],
"creature": [
{
"type": "minecraft:sheep",
"maxCount": 4,
"minCount": 4,
"weight": 12
},
{
"type": "minecraft:pig",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:chicken",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:cow",
"maxCount": 4,
"minCount": 4,
"weight": 8
},
{
"type": "minecraft:horse",
"maxCount": 6,
"minCount": 2,
"weight": 5
},
{
"type": "minecraft:donkey",
"maxCount": 3,
"minCount": 1,
"weight": 1
}
],
"misc": [],
"monster": [
{
"type": "minecraft:spider",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:zombie",
"maxCount": 4,
"minCount": 4,
"weight": 95
},
{
"type": "minecraft:zombie_villager",
"maxCount": 1,
"minCount": 1,
"weight": 5
},
{
"type": "minecraft:skeleton",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:creeper",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:slime",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:enderman",
"maxCount": 4,
"minCount": 1,
"weight": 10
},
{
"type": "minecraft:witch",
"maxCount": 1,
"minCount": 1,
"weight": 5
}
],
"underground_water_creature": [
{
"type": "minecraft:glow_squid",
"maxCount": 6,
"minCount": 4,
"weight": 10
}
],
"water_ambient": [],
"water_creature": []
},
"temperature": 0.8
}

View file

@ -0,0 +1,106 @@
{
"carvers": {
"air": "minecraft:nether_cave"
},
"downfall": 0.0,
"effects": {
"additions_sound": {
"sound": "minecraft:ambient.crimson_forest.additions",
"tick_chance": 0.0111
},
"ambient_sound": "minecraft:ambient.crimson_forest.loop",
"fog_color": 3343107,
"mood_sound": {
"block_search_extent": 8,
"offset": 2.0,
"sound": "minecraft:ambient.crimson_forest.mood",
"tick_delay": 6000
},
"music": {
"max_delay": 24000,
"min_delay": 12000,
"replace_current_music": false,
"sound": "minecraft:music.nether.crimson_forest"
},
"particle": {
"options": {
"type": "minecraft:crimson_spore"
},
"probability": 0.025
},
"sky_color": 7254527,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [
[],
[],
[],
[],
[],
[],
[],
[
"minecraft:spring_open",
"minecraft:patch_fire",
"minecraft:glowstone_extra",
"minecraft:glowstone",
"minecraft:ore_magma",
"minecraft:spring_closed",
"minecraft:ore_gravel_nether",
"minecraft:ore_blackstone",
"minecraft:ore_gold_nether",
"minecraft:ore_quartz_nether",
"minecraft:ore_ancient_debris_large",
"minecraft:ore_debris_small"
],
[],
[
"minecraft:spring_lava",
"minecraft:brown_mushroom_normal",
"minecraft:red_mushroom_normal",
"minecraft:weeping_vines",
"minecraft:crimson_fungi",
"minecraft:crimson_forest_vegetation"
]
],
"precipitation": "none",
"spawn_costs": {},
"spawners": {
"ambient": [],
"axolotls": [],
"creature": [
{
"type": "minecraft:strider",
"maxCount": 2,
"minCount": 1,
"weight": 60
}
],
"misc": [],
"monster": [
{
"type": "minecraft:zombified_piglin",
"maxCount": 4,
"minCount": 2,
"weight": 1
},
{
"type": "minecraft:hoglin",
"maxCount": 4,
"minCount": 3,
"weight": 9
},
{
"type": "minecraft:piglin",
"maxCount": 4,
"minCount": 3,
"weight": 5
}
],
"underground_water_creature": [],
"water_ambient": [],
"water_creature": []
},
"temperature": 2.0
}

View file

@ -0,0 +1,130 @@
{
"carvers": {},
"downfall": 0.5,
"effects": {
"fog_color": 10518688,
"mood_sound": {
"block_search_extent": 8,
"offset": 2.0,
"sound": "minecraft:ambient.cave",
"tick_delay": 6000
},
"sky_color": 0,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [],
"precipitation": "none",
"spawn_costs": {},
"spawners": {
"ambient": [
{
"type": "minecraft:bat",
"maxCount": 8,
"minCount": 8,
"weight": 10
}
],
"axolotls": [],
"creature": [
{
"type": "minecraft:sheep",
"maxCount": 4,
"minCount": 4,
"weight": 12
},
{
"type": "minecraft:pig",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:chicken",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:cow",
"maxCount": 4,
"minCount": 4,
"weight": 8
},
{
"type": "minecraft:horse",
"maxCount": 6,
"minCount": 2,
"weight": 5
},
{
"type": "minecraft:donkey",
"maxCount": 3,
"minCount": 1,
"weight": 1
}
],
"misc": [],
"monster": [
{
"type": "minecraft:spider",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:zombie",
"maxCount": 4,
"minCount": 4,
"weight": 95
},
{
"type": "minecraft:zombie_villager",
"maxCount": 1,
"minCount": 1,
"weight": 5
},
{
"type": "minecraft:skeleton",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:creeper",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:slime",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:enderman",
"maxCount": 4,
"minCount": 1,
"weight": 10
},
{
"type": "minecraft:witch",
"maxCount": 1,
"minCount": 1,
"weight": 5
}
],
"underground_water_creature": [
{
"type": "minecraft:glow_squid",
"maxCount": 6,
"minCount": 4,
"weight": 10
}
],
"water_ambient": [],
"water_creature": []
},
"temperature": 0.5
}

View file

@ -0,0 +1,138 @@
{
"carvers": {},
"downfall": 0.5,
"effects": {
"fog_color": 10518688,
"mood_sound": {
"block_search_extent": 8,
"offset": 2.0,
"sound": "minecraft:ambient.cave",
"tick_delay": 6000
},
"sky_color": 0,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [
[],
[],
[],
[],
[
"minecraft:end_gateway_return"
]
],
"precipitation": "none",
"spawn_costs": {},
"spawners": {
"ambient": [
{
"type": "minecraft:bat",
"maxCount": 8,
"minCount": 8,
"weight": 10
}
],
"axolotls": [],
"creature": [
{
"type": "minecraft:sheep",
"maxCount": 4,
"minCount": 4,
"weight": 12
},
{
"type": "minecraft:pig",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:chicken",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:cow",
"maxCount": 4,
"minCount": 4,
"weight": 8
},
{
"type": "minecraft:horse",
"maxCount": 6,
"minCount": 2,
"weight": 5
},
{
"type": "minecraft:donkey",
"maxCount": 3,
"minCount": 1,
"weight": 1
}
],
"misc": [],
"monster": [
{
"type": "minecraft:spider",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:zombie",
"maxCount": 4,
"minCount": 4,
"weight": 95
},
{
"type": "minecraft:zombie_villager",
"maxCount": 1,
"minCount": 1,
"weight": 5
},
{
"type": "minecraft:skeleton",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:creeper",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:slime",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:enderman",
"maxCount": 4,
"minCount": 1,
"weight": 10
},
{
"type": "minecraft:witch",
"maxCount": 1,
"minCount": 1,
"weight": 5
}
],
"underground_water_creature": [
{
"type": "minecraft:glow_squid",
"maxCount": 6,
"minCount": 4,
"weight": 10
}
],
"water_ambient": [],
"water_creature": []
},
"temperature": 0.5
}

View file

@ -0,0 +1,130 @@
{
"carvers": {},
"downfall": 0.5,
"effects": {
"fog_color": 10518688,
"mood_sound": {
"block_search_extent": 8,
"offset": 2.0,
"sound": "minecraft:ambient.cave",
"tick_delay": 6000
},
"sky_color": 0,
"water_color": 4159204,
"water_fog_color": 329011
},
"features": [],
"precipitation": "none",
"spawn_costs": {},
"spawners": {
"ambient": [
{
"type": "minecraft:bat",
"maxCount": 8,
"minCount": 8,
"weight": 10
}
],
"axolotls": [],
"creature": [
{
"type": "minecraft:sheep",
"maxCount": 4,
"minCount": 4,
"weight": 12
},
{
"type": "minecraft:pig",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:chicken",
"maxCount": 4,
"minCount": 4,
"weight": 10
},
{
"type": "minecraft:cow",
"maxCount": 4,
"minCount": 4,
"weight": 8
},
{
"type": "minecraft:horse",
"maxCount": 6,
"minCount": 2,
"weight": 5
},
{
"type": "minecraft:donkey",
"maxCount": 3,
"minCount": 1,
"weight": 1
}
],
"misc": [],
"monster": [
{
"type": "minecraft:spider",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:zombie",
"maxCount": 4,
"minCount": 4,
"weight": 95
},
{
"type": "minecraft:zombie_villager",
"maxCount": 1,
"minCount": 1,
"weight": 5
},
{
"type": "minecraft:skeleton",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:creeper",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:slime",
"maxCount": 4,
"minCount": 4,
"weight": 100
},
{
"type": "minecraft:enderman",
"maxCount": 4,
"minCount": 1,
"weight": 10
},
{
"type": "minecraft:witch",
"maxCount": 1,
"minCount": 1,
"weight": 5
}
],
"underground_water_creature": [
{
"type": "minecraft:glow_squid",
"maxCount": 6,
"minCount": 4,
"weight": 10
}
],
"water_ambient": [],
"water_creature": []
},
"temperature": 0.5
}

View file

@ -0,0 +1,4 @@
{
"type": "minecraft:desert_well",
"config": {}
}

View file

@ -0,0 +1,15 @@
{
"feature": "fabric-biome-api-v1-testmod:fab_desert_well",
"placement": [
{
"type": "minecraft:in_square"
},
{
"type": "minecraft:heightmap",
"heightmap": "MOTION_BLOCKING"
},
{
"type": "minecraft:biome"
}
]
}

View file

@ -14,14 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.impl.client.texture; package net.fabricmc.fabric.test.biome;
import net.minecraft.client.texture.NativeImage; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
import net.minecraft.client.texture.Sprite; import net.fabricmc.fabric.api.datagen.v1.provider.FabricBuiltinRegistriesProvider;
import net.minecraft.client.texture.SpriteAtlasTexture;
public class FabricSprite extends Sprite { public class DataGeneratorEntrypoint implements net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint {
public FabricSprite(SpriteAtlasTexture spriteAtlasTexture, Sprite.Info info, int mipmap, int u, int v, int x, int y, NativeImage nativeImage) { @Override
super(spriteAtlasTexture, info, mipmap, u, v, x, y, nativeImage); public void onInitializeDataGenerator(FabricDataGenerator dataGenerator) {
dataGenerator.addProvider(FabricBuiltinRegistriesProvider.forCurrentMod());
} }
} }

View file

@ -71,16 +71,16 @@ public class FabricBiomeTest implements ModInitializer {
private static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_barrens")); private static final RegistryKey<Biome> TEST_END_BARRRENS = RegistryKey.of(Registry.BIOME_KEY, new Identifier(MOD_ID, "test_end_barrens"));
@Override @Override
public void onInitialize() { public void onInitialize() {
Registry.register(BuiltinRegistries.BIOME, TEST_CRIMSON_FOREST.getValue(), TheNetherBiomeCreator.createCrimsonForest()); 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(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)); NetherBiomes.addNetherBiome(TEST_CRIMSON_FOREST, MultiNoiseUtil.createNoiseHypercube(0.0F, -0.15F, 0.0f, 0.0F, 0.0f, 0.0F, 0.2F));
Registry.register(BuiltinRegistries.BIOME, CUSTOM_PLAINS.getValue(), OverworldBiomeCreator.createPlains(false, false, false)); BuiltinRegistries.add(BuiltinRegistries.BIOME, CUSTOM_PLAINS.getValue(), OverworldBiomeCreator.createPlains(false, false, false));
Registry.register(BuiltinRegistries.BIOME, TEST_END_HIGHLANDS.getValue(), createEndHighlands()); BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_HIGHLANDS.getValue(), createEndHighlands());
Registry.register(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands()); BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_MIDLANDS.getValue(), createEndMidlands());
Registry.register(BuiltinRegistries.BIOME, TEST_END_BARRRENS.getValue(), createEndBarrens()); BuiltinRegistries.add(BuiltinRegistries.BIOME, TEST_END_BARRRENS.getValue(), createEndBarrens());
// TESTING HINT: to get to the end: // TESTING HINT: to get to the end:
// /execute in minecraft:the_end run tp @s 0 90 0 // /execute in minecraft:the_end run tp @s 0 90 0
@ -90,12 +90,12 @@ public class FabricBiomeTest implements ModInitializer {
TheEndBiomes.addBarrensBiome(TEST_END_HIGHLANDS, TEST_END_BARRRENS, 10.0); TheEndBiomes.addBarrensBiome(TEST_END_HIGHLANDS, TEST_END_BARRRENS, 10.0);
ConfiguredFeature<?, ?> COMMON_DESERT_WELL = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE); ConfiguredFeature<?, ?> COMMON_DESERT_WELL = new ConfiguredFeature<>(Feature.DESERT_WELL, DefaultFeatureConfig.INSTANCE);
Registry.register(BuiltinRegistries.CONFIGURED_FEATURE, new Identifier(MOD_ID, "fab_desert_well"), COMMON_DESERT_WELL); 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()); 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 // 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())); PlacedFeature PLACED_COMMON_DESERT_WELL = new PlacedFeature(featureEntry, List.of(SquarePlacementModifier.of(), PlacedFeatures.MOTION_BLOCKING_HEIGHTMAP, BiomePlacementModifier.of()));
Registry.register(BuiltinRegistries.PLACED_FEATURE, new Identifier(MOD_ID, "fab_desert_well"), PLACED_COMMON_DESERT_WELL); BuiltinRegistries.add(BuiltinRegistries.PLACED_FEATURE, new Identifier(MOD_ID, "fab_desert_well"), PLACED_COMMON_DESERT_WELL);
BiomeModifications.create(new Identifier("fabric:test_mod")) BiomeModifications.create(new Identifier("fabric:test_mod"))
.add(ModificationPhase.ADDITIONS, .add(ModificationPhase.ADDITIONS,

View file

@ -11,6 +11,9 @@
"entrypoints": { "entrypoints": {
"main": [ "main": [
"net.fabricmc.fabric.test.biome.FabricBiomeTest" "net.fabricmc.fabric.test.biome.FabricBiomeTest"
],
"fabric-datagen": [
"net.fabricmc.fabric.test.biome.DataGeneratorEntrypoint"
] ]
} }
} }

View file

@ -23,13 +23,17 @@ import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.network.ClientCommandSource; import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.client.network.ClientDynamicRegistryType;
import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.CommandRegistryAccess; import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.CommandSource; import net.minecraft.command.CommandSource;
import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket; import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.util.registry.CombinedDynamicRegistries;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
@ -44,11 +48,17 @@ abstract class ClientPlayNetworkHandlerMixin {
@Final @Final
private ClientCommandSource commandSource; private ClientCommandSource commandSource;
@Shadow
private FeatureSet field_40482;
@Shadow
private CombinedDynamicRegistries<ClientDynamicRegistryType> registryManager;
@Inject(method = "onGameJoin", at = @At("RETURN")) @Inject(method = "onGameJoin", at = @At("RETURN"))
private void onGameJoin(GameJoinS2CPacket packet, CallbackInfo info) { private void onGameJoin(GameJoinS2CPacket packet, CallbackInfo info) {
final CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>(); final CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>();
ClientCommandInternals.setActiveDispatcher(dispatcher); ClientCommandInternals.setActiveDispatcher(dispatcher);
ClientCommandRegistrationCallback.EVENT.invoker().register(dispatcher, new CommandRegistryAccess(packet.registryManager())); ClientCommandRegistrationCallback.EVENT.invoker().register(dispatcher, new CommandRegistryAccess(this.registryManager.getCombinedRegistryManager(), this.field_40482));
ClientCommandInternals.finalizeInit(); ClientCommandInternals.finalizeInit();
} }
@ -60,4 +70,18 @@ abstract class ClientPlayNetworkHandlerMixin {
// to be in the same dispatcher and completion results. // to be in the same dispatcher and completion results.
ClientCommandInternals.addCommands((CommandDispatcher) commandDispatcher, (FabricClientCommandSource) commandSource); ClientCommandInternals.addCommands((CommandDispatcher) commandDispatcher, (FabricClientCommandSource) commandSource);
} }
@Inject(method = "method_45731", at = @At("HEAD"), cancellable = true)
private void onSendCommand(String command, CallbackInfoReturnable<Boolean> cir) {
if (ClientCommandInternals.executeCommand(command)) {
cir.setReturnValue(true);
}
}
@Inject(method = "method_45730", at = @At("HEAD"), cancellable = true)
private void onSendCommand(String command, CallbackInfo info) {
if (ClientCommandInternals.executeCommand(command)) {
info.cancel();
}
}
} }

View file

@ -1,45 +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.command.client;
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.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.text.Text;
import net.fabricmc.fabric.impl.command.client.ClientCommandInternals;
@Mixin(ClientPlayerEntity.class)
abstract class ClientPlayerEntityMixin {
@Inject(method = "sendCommand(Ljava/lang/String;)Z", at = @At("HEAD"), cancellable = true)
private void onSendCommand(String command, CallbackInfoReturnable<Boolean> cir) {
if (ClientCommandInternals.executeCommand(command)) {
cir.setReturnValue(true);
}
}
@Inject(method = "sendCommand(Ljava/lang/String;Lnet/minecraft/text/Text;)V", at = @At("HEAD"), cancellable = true)
private void onSendCommand(String command, Text preview, CallbackInfo info) {
if (ClientCommandInternals.executeCommand(command)) {
info.cancel();
}
}
}

View file

@ -4,7 +4,6 @@
"compatibilityLevel": "JAVA_16", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"ClientCommandSourceMixin", "ClientCommandSourceMixin",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin" "ClientPlayNetworkHandlerMixin"
], ],
"injectors": { "injectors": {

View file

@ -19,9 +19,9 @@ package net.fabricmc.fabric.api.registry;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.minecraft.block.SculkSensorBlock;
import net.minecraft.tag.GameEventTags; import net.minecraft.tag.GameEventTags;
import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.GameEvent;
import net.minecraft.world.event.listener.VibrationListener;
/** /**
* Provides a method for registering sculk sensor frequencies. * Provides a method for registering sculk sensor frequencies.
@ -51,7 +51,7 @@ public final class SculkSensorFrequencyRegistry {
throw new IllegalArgumentException("Attempted to register Sculk Sensor frequency for event "+event.getId()+" with frequency "+frequency+". Sculk Sensor frequencies must be between 1 and 15 inclusive."); throw new IllegalArgumentException("Attempted to register Sculk Sensor frequency for event "+event.getId()+" with frequency "+frequency+". Sculk Sensor frequencies must be between 1 and 15 inclusive.");
} }
int replaced = SculkSensorBlock.FREQUENCIES.put(event, frequency); int replaced = VibrationListener.field_40356.put(event, frequency);
if (replaced != 0) { if (replaced != 0) {
LOGGER.debug("Replaced old frequency mapping for {} - was {}, now {}", event.getId(), replaced, frequency); LOGGER.debug("Replaced old frequency mapping for {} - was {}, now {}", event.getId(), replaced, frequency);

View file

@ -23,9 +23,10 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.block.SculkSensorBlock; import net.minecraft.block.SculkSensorBlock;
import net.minecraft.world.event.listener.VibrationListener;
@Mixin(SculkSensorBlock.class) @Mixin(VibrationListener.class)
public class SculkSensorBlockMixin { public class VibrationListenerMixin {
/** /**
* Redirects the call to {@linkplain Object2IntMaps#unmodifiable(Object2IntMap)} in initialization of {@linkplain SculkSensorBlock#FREQUENCIES}. * Redirects the call to {@linkplain Object2IntMaps#unmodifiable(Object2IntMap)} in initialization of {@linkplain SculkSensorBlock#FREQUENCIES}.
*/ */

View file

@ -13,7 +13,7 @@
"AbstractFurnaceBlockEntityMixin", "AbstractFurnaceBlockEntityMixin",
"FireBlockMixin", "FireBlockMixin",
"OxidizableMixin", "OxidizableMixin",
"SculkSensorBlockMixin", "VibrationListenerMixin",
"ShovelItemAccessor", "ShovelItemAccessor",
"VillagerEntityAccessor", "VillagerEntityAccessor",
"VillagerEntityMixin" "VillagerEntityMixin"

View file

@ -6,7 +6,7 @@ moduleDependencies(project, [
'fabric-registry-sync-v0', 'fabric-registry-sync-v0',
'fabric-networking-api-v1', 'fabric-networking-api-v1',
'fabric-resource-conditions-api-v1', 'fabric-resource-conditions-api-v1',
'fabric-item-groups-v0' 'fabric-item-group-api-v1'
]) ])
dependencies { dependencies {
@ -63,7 +63,7 @@ task generateAccessWidener() {
File inputJar = loom.namedMinecraftProvider.parentMinecraftProvider.commonJar.toFile() File inputJar = loom.namedMinecraftProvider.parentMinecraftProvider.commonJar.toFile()
String accessWidener = file("template.accesswidener").text + "\n" String accessWidener = file("template.accesswidener").text + "\n"
visitMethods(inputJar, "net/minecraft/data/server/RecipeProvider.class") { name, desc, owner -> visitMethods(inputJar, "net/minecraft/data/server/recipe/RecipeProvider.class") { name, desc, owner ->
if (it.name == "generate") if (it.name == "generate")
return return
@ -78,7 +78,7 @@ task generateAccessWidener() {
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n" accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
} }
visitMethods(inputJar, "net/minecraft/data/server/BlockLootTableGenerator.class") { name, desc, owner -> visitMethods(inputJar, "net/minecraft/data/server/loottable/BlockLootTableGenerator.class") { name, desc, owner ->
accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n" accessWidener += "transitive-accessible\tmethod\t${owner}\t${name}\t${desc}\n"
} }

View file

@ -17,7 +17,6 @@
package net.fabricmc.fabric.api.datagen.v1; package net.fabricmc.fabric.api.datagen.v1;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Collections;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
@ -25,8 +24,10 @@ import org.jetbrains.annotations.ApiStatus;
import net.minecraft.SharedConstants; import net.minecraft.SharedConstants;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataGenerator;
import net.minecraft.data.DataOutput;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.fabricmc.fabric.impl.datagen.FabricDataOutput;
import net.fabricmc.loader.api.ModContainer; import net.fabricmc.loader.api.ModContainer;
/** /**
@ -38,9 +39,16 @@ public final class FabricDataGenerator extends DataGenerator {
@ApiStatus.Internal @ApiStatus.Internal
public FabricDataGenerator(Path output, ModContainer mod, boolean strictValidation) { public FabricDataGenerator(Path output, ModContainer mod, boolean strictValidation) {
super(output, Collections.emptyList(), SharedConstants.getGameVersion(), true); super(output, SharedConstants.getGameVersion(), true);
this.modContainer = Objects.requireNonNull(mod); this.modContainer = Objects.requireNonNull(mod);
this.strictValidation = strictValidation; this.strictValidation = strictValidation;
this.output = new FabricDataOutput(this, output);
}
@Override
public DataOutput getOutputFor(String packName) {
return new FabricDataOutput(this, super.getOutputFor(packName).getPath());
} }
/** /**

View file

@ -26,7 +26,7 @@ import com.google.common.collect.Sets;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.advancement.Advancement; import net.minecraft.advancement.Advancement;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataOutput;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -42,11 +42,11 @@ import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper;
*/ */
public abstract class FabricAdvancementProvider implements DataProvider { public abstract class FabricAdvancementProvider implements DataProvider {
protected final FabricDataGenerator dataGenerator; protected final FabricDataGenerator dataGenerator;
private final DataGenerator.PathResolver pathResolver; private final DataOutput.PathResolver pathResolver;
protected FabricAdvancementProvider(FabricDataGenerator dataGenerator) { protected FabricAdvancementProvider(FabricDataGenerator dataGenerator) {
this.dataGenerator = dataGenerator; this.dataGenerator = dataGenerator;
this.pathResolver = dataGenerator.createPathResolver(DataGenerator.OutputType.DATA_PACK, "advancements"); this.pathResolver = dataGenerator.getOutput().getResolver(DataOutput.OutputType.DATA_PACK, "advancements");
} }
/** /**
@ -87,7 +87,7 @@ public abstract class FabricAdvancementProvider implements DataProvider {
} }
private Path getOutputPath(Advancement advancement) { private Path getOutputPath(Advancement advancement) {
return dataGenerator.getOutput().resolve("data/%s/advancements/%s.json".formatted(advancement.getId().getNamespace(), advancement.getId().getPath())); return pathResolver.resolveJson(advancement.getId());
} }
@Override @Override

View file

@ -16,6 +16,7 @@
package net.fabricmc.fabric.api.datagen.v1.provider; package net.fabricmc.fabric.api.datagen.v1.provider;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -24,18 +25,19 @@ import java.util.function.BiConsumer;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.server.BlockLootTableGenerator; import net.minecraft.data.server.loottable.BlockLootTableGenerator;
import net.minecraft.loot.LootTable; import net.minecraft.loot.LootTable;
import net.minecraft.loot.LootTables; import net.minecraft.loot.LootTables;
import net.minecraft.loot.context.LootContextType; import net.minecraft.loot.context.LootContextType;
import net.minecraft.loot.context.LootContextTypes; import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.resource.featuretoggle.FeatureFlags;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
/** /**
* Extend this class and implement {@link FabricBlockLootTableProvider#generateBlockLootTables}. * Extend this class and implement {@link FabricBlockLootTableProvider#generate}.
* *
* <p>Register an instance of the class with {@link FabricDataGenerator#addProvider} in a {@link net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint} * <p>Register an instance of the class with {@link FabricDataGenerator#addProvider} in a {@link net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint}
*/ */
@ -44,6 +46,7 @@ public abstract class FabricBlockLootTableProvider extends BlockLootTableGenerat
private final Set<Identifier> excludedFromStrictValidation = new HashSet<>(); private final Set<Identifier> excludedFromStrictValidation = new HashSet<>();
protected FabricBlockLootTableProvider(FabricDataGenerator dataGenerator) { protected FabricBlockLootTableProvider(FabricDataGenerator dataGenerator) {
super(Collections.emptySet(), FeatureFlags.FEATURE_MANAGER.getFeatureSet());
this.dataGenerator = dataGenerator; this.dataGenerator = dataGenerator;
} }
@ -52,7 +55,8 @@ public abstract class FabricBlockLootTableProvider extends BlockLootTableGenerat
* *
* <p>Use the range of {@link BlockLootTableGenerator#addDrop} methods to generate block drops. * <p>Use the range of {@link BlockLootTableGenerator#addDrop} methods to generate block drops.
*/ */
protected abstract void generateBlockLootTables(); @Override
public abstract void generate();
/** /**
* Disable strict validation for the passed block. * Disable strict validation for the passed block.
@ -73,7 +77,7 @@ public abstract class FabricBlockLootTableProvider extends BlockLootTableGenerat
@Override @Override
public void accept(BiConsumer<Identifier, LootTable.Builder> biConsumer) { public void accept(BiConsumer<Identifier, LootTable.Builder> biConsumer) {
generateBlockLootTables(); generate();
for (Map.Entry<Identifier, LootTable.Builder> entry : lootTables.entrySet()) { for (Map.Entry<Identifier, LootTable.Builder> entry : lootTables.entrySet()) {
Identifier identifier = entry.getKey(); Identifier identifier = entry.getKey();

View file

@ -0,0 +1,115 @@
/*
* 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.io.IOException;
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
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;
/**
* 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 DataOutput output;
private FabricBuiltinRegistriesProvider(DataOutput 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 Function<FabricDataGenerator, DataProvider> forCurrentMod() {
return fabricDataGenerator -> new FabricBuiltinRegistriesProvider(
fabricDataGenerator.getOutput(),
e -> e.getValue().getNamespace().equals(fabricDataGenerator.getModId())
);
}
@Override
public void run(DataWriter writer) {
DynamicRegistryManager dynamicRegistryManager = BuiltinRegistries.createBuiltinRegistryManager();
DynamicOps<JsonElement> dynamicOps = RegistryOps.of(JsonOps.INSTANCE, dynamicRegistryManager);
RegistryLoader.DYNAMIC_REGISTRIES.forEach((info) -> this.writeRegistryEntries(writer, dynamicRegistryManager, dynamicOps, info));
}
private <T> void 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());
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());
writeToPath(path, writer, ops, registry.elementCodec(), regEntry.getValue());
}
}
private static <E> void writeToPath(Path path, DataWriter cache, DynamicOps<JsonElement> json, Encoder<E> encoder, E value) {
try {
Optional<JsonElement> optional = encoder.encodeStart(json, value).resultOrPartial((error) -> {
LOGGER.error("Couldn't serialize element {}: {}", path, error);
});
if (optional.isPresent()) {
DataProvider.writeToPath(cache, optional.get(), path);
}
} catch (IOException var6) {
LOGGER.error("Couldn't save element {}", path, var6);
}
}
@Override
public String getName() {
return "Built-In Registry Content";
}
}

View file

@ -29,6 +29,7 @@ import com.google.gson.JsonParser;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.DataOutput;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.Enchantment;
@ -93,7 +94,9 @@ public abstract class FabricLanguageProvider implements DataProvider {
} }
private Path getLangFilePath(String code) { private Path getLangFilePath(String code) {
return dataGenerator.getOutput().resolve("assets/%s/lang/%s.json".formatted(dataGenerator.getModId(), code)); return dataGenerator.getOutput()
.getResolver(DataOutput.OutputType.RESOURCE_PACK, "lang")
.resolveJson(new Identifier(dataGenerator.getModId(), code));
} }
@Override @Override
@ -117,15 +120,17 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for an {@link Item}. * Adds a translation for an {@link Item}.
*
* @param item The {@link Item} to get the translation key from. * @param item The {@link Item} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
default void add(Item item, String value) { default void add(Item item, String value) {
add(item.getTranslationKey(), value); add(item.getTranslationKey(), value);
}; }
/** /**
* Adds a translation for a {@link Block}. * Adds a translation for a {@link Block}.
*
* @param block The {@link Block} to get the translation key from. * @param block The {@link Block} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -135,15 +140,17 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for an {@link ItemGroup}. * Adds a translation for an {@link ItemGroup}.
*
* @param group The {@link ItemGroup} to get the translation key from. * @param group The {@link ItemGroup} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
default void add(ItemGroup group, String value) { default void add(ItemGroup group, String value) {
add("itemGroup." + group.getName(), value); add(group.getDisplayName().toString(), value);
} }
/** /**
* Adds a translation for an {@link EntityType}. * Adds a translation for an {@link EntityType}.
*
* @param entityType The {@link EntityType} to get the translation key from. * @param entityType The {@link EntityType} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -153,6 +160,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for an {@link Enchantment}. * Adds a translation for an {@link Enchantment}.
*
* @param enchantment The {@link Enchantment} to get the translation key from. * @param enchantment The {@link Enchantment} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -162,6 +170,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for an {@link EntityAttribute}. * Adds a translation for an {@link EntityAttribute}.
*
* @param entityAttribute The {@link EntityAttribute} to get the translation key from. * @param entityAttribute The {@link EntityAttribute} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -171,6 +180,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for a {@link StatType}. * Adds a translation for a {@link StatType}.
*
* @param statType The {@link StatType} to get the translation key from. * @param statType The {@link StatType} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -180,6 +190,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for a {@link StatusEffect}. * Adds a translation for a {@link StatusEffect}.
*
* @param statusEffect The {@link StatusEffect} to get the translation key from. * @param statusEffect The {@link StatusEffect} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -189,6 +200,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Adds a translation for an {@link Identifier}. * Adds a translation for an {@link Identifier}.
*
* @param identifier The {@link Identifier} to get the translation key from. * @param identifier The {@link Identifier} to get the translation key from.
* @param value The value of the entry. * @param value The value of the entry.
*/ */
@ -198,6 +210,7 @@ public abstract class FabricLanguageProvider implements DataProvider {
/** /**
* Merges an existing language file into the generated language file. * Merges an existing language file into the generated language file.
*
* @param existingLanguageFile The path to the existing language file. * @param existingLanguageFile The path to the existing language file.
* @throws IOException If loading the language file failed. * @throws IOException If loading the language file failed.
*/ */

View file

@ -28,6 +28,7 @@ import com.google.common.collect.Maps;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.ApiStatus;
import net.minecraft.data.DataOutput;
import net.minecraft.data.DataProvider; import net.minecraft.data.DataProvider;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.loot.LootManager; import net.minecraft.loot.LootManager;
@ -87,6 +88,6 @@ public interface FabricLootTableProvider extends Consumer<BiConsumer<Identifier,
} }
private Path getOutputPath(Identifier lootTableId) { private Path getOutputPath(Identifier lootTableId) {
return getFabricDataGenerator().getOutput().resolve("data/%s/loot_tables/%s.json".formatted(lootTableId.getNamespace(), lootTableId.getPath())); return getFabricDataGenerator().getOutput().getResolver(DataOutput.OutputType.DATA_PACK, "loot_tables").resolveJson(lootTableId);
} }
} }

View file

@ -31,7 +31,7 @@ public abstract class FabricModelProvider extends ModelProvider {
protected final FabricDataGenerator dataGenerator; protected final FabricDataGenerator dataGenerator;
public FabricModelProvider(FabricDataGenerator dataGenerator) { public FabricModelProvider(FabricDataGenerator dataGenerator) {
super(dataGenerator); super(dataGenerator.getOutput());
this.dataGenerator = dataGenerator; this.dataGenerator = dataGenerator;
} }

View file

@ -24,8 +24,8 @@ import com.google.common.collect.Sets;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.data.server.RecipeProvider;
import net.minecraft.data.server.recipe.RecipeJsonProvider; import net.minecraft.data.server.recipe.RecipeJsonProvider;
import net.minecraft.data.server.recipe.RecipeProvider;
import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder;
import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -35,7 +35,7 @@ import net.fabricmc.fabric.api.resource.conditions.v1.ConditionJsonProvider;
import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper; import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper;
/** /**
* Extend this class and implement {@link FabricRecipeProvider#generateRecipes}. * Extend this class and implement {@link FabricRecipeProvider#generate}.
* *
* <p>Register an instance of the class with {@link FabricDataGenerator#addProvider} in a {@link net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint} * <p>Register an instance of the class with {@link FabricDataGenerator#addProvider} in a {@link net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint}
*/ */
@ -43,14 +43,15 @@ public abstract class FabricRecipeProvider extends RecipeProvider {
protected final FabricDataGenerator dataGenerator; protected final FabricDataGenerator dataGenerator;
public FabricRecipeProvider(FabricDataGenerator dataGenerator) { public FabricRecipeProvider(FabricDataGenerator dataGenerator) {
super(dataGenerator); super(dataGenerator.getOutput());
this.dataGenerator = dataGenerator; this.dataGenerator = dataGenerator;
} }
/** /**
* Implement this method and then use the range of methods in {@link RecipeProvider} or from one of the recipe json factories such as {@link ShapedRecipeJsonBuilder} or {@link ShapelessRecipeJsonBuilder}. * Implement this method and then use the range of methods in {@link RecipeProvider} or from one of the recipe json factories such as {@link ShapedRecipeJsonBuilder} or {@link ShapelessRecipeJsonBuilder}.
*/ */
protected abstract void generateRecipes(Consumer<RecipeJsonProvider> exporter); @Override
public abstract void generate(Consumer<RecipeJsonProvider> exporter);
/** /**
* Return a new exporter that applies the specified conditions to any recipe json provider it receives. * Return a new exporter that applies the specified conditions to any recipe json provider it receives.
@ -66,7 +67,7 @@ public abstract class FabricRecipeProvider extends RecipeProvider {
@Override @Override
public void run(DataWriter writer) { public void run(DataWriter writer) {
Set<Identifier> generatedRecipes = Sets.newHashSet(); Set<Identifier> generatedRecipes = Sets.newHashSet();
generateRecipes(provider -> { generate(provider -> {
Identifier identifier = getRecipeIdentifier(provider.getRecipeId()); Identifier identifier = getRecipeIdentifier(provider.getRecipeId());
if (!generatedRecipes.add(identifier)) { if (!generatedRecipes.add(identifier)) {
@ -87,6 +88,11 @@ public abstract class FabricRecipeProvider extends RecipeProvider {
}); });
} }
@Override
public String getName() {
return "Recipes";
}
/** /**
* Override this method to change the recipe identifier. The default implementation normalizes the namespace to the mod ID. * Override this method to change the recipe identifier. The default implementation normalizes the namespace to the mod ID.
*/ */

View file

@ -19,32 +19,31 @@ package net.fabricmc.fabric.api.datagen.v1.provider;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import com.google.common.base.Preconditions;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.server.AbstractTagProvider; import net.minecraft.data.server.tag.AbstractTagProvider;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluid;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.tag.BlockTags; import net.minecraft.tag.BlockTags;
import net.minecraft.tag.TagBuilder;
import net.minecraft.tag.EntityTypeTags; import net.minecraft.tag.EntityTypeTags;
import net.minecraft.tag.FluidTags; import net.minecraft.tag.FluidTags;
import net.minecraft.tag.GameEventTags; import net.minecraft.tag.GameEventTags;
import net.minecraft.tag.ItemTags; import net.minecraft.tag.ItemTags;
import net.minecraft.tag.TagBuilder;
import net.minecraft.tag.TagEntry; import net.minecraft.tag.TagEntry;
import net.minecraft.tag.TagKey; import net.minecraft.tag.TagKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.BuiltinRegistries; import net.minecraft.util.registry.BuiltinRegistries;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.RegistryKey;
import net.minecraft.util.registry.RegistryLoader;
import net.minecraft.world.event.GameEvent; import net.minecraft.world.event.GameEvent;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper; import net.fabricmc.fabric.impl.datagen.FabricDataGenHelper;
import net.fabricmc.fabric.impl.datagen.ForcedTagEntry; import net.fabricmc.fabric.impl.datagen.ForcedTagEntry;
import net.fabricmc.fabric.mixin.datagen.DynamicRegistryManagerAccessor;
/** /**
* Implement this class (or one of the inner classes) to generate a tag list. * Implement this class (or one of the inner classes) to generate a tag list.
@ -72,7 +71,7 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
* @param registry The backing registry for the Tag type. * @param registry The backing registry for the Tag type.
*/ */
public FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry) { public FabricTagProvider(FabricDataGenerator dataGenerator, Registry<T> registry) {
super(dataGenerator, registry); super(dataGenerator.getOutput(), registry);
this.fabricDataGenerator = dataGenerator; this.fabricDataGenerator = dataGenerator;
if (!(this instanceof DynamicRegistryTagProvider) && BuiltinRegistries.REGISTRIES.contains((RegistryKey) registry.getKey())) { if (!(this instanceof DynamicRegistryTagProvider) && BuiltinRegistries.REGISTRIES.contains((RegistryKey) registry.getKey())) {
@ -194,7 +193,10 @@ public abstract class FabricTagProvider<T> extends AbstractTagProvider<T> {
*/ */
protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey) { protected DynamicRegistryTagProvider(FabricDataGenerator dataGenerator, RegistryKey<? extends Registry<T>> registryKey) {
super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(registryKey)); super(dataGenerator, FabricDataGenHelper.getFakeDynamicRegistry(registryKey));
Preconditions.checkArgument(DynamicRegistryManagerAccessor.getInfos().containsKey(registryKey), "Only dynamic registries are supported in this tag provider."); 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.");
}
} }
} }

View file

@ -31,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import net.minecraft.data.server.AbstractTagProvider; import net.minecraft.data.server.tag.AbstractTagProvider;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.RegistryKey;
@ -138,7 +138,7 @@ public final class FabricDataGenHelper {
*/ */
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public static <T> Registry<T> getFakeDynamicRegistry(RegistryKey<? extends Registry<T>> registryKey) { public static <T> Registry<T> getFakeDynamicRegistry(RegistryKey<? extends Registry<T>> registryKey) {
return new SimpleRegistry<>(registryKey, Lifecycle.experimental(), null) { return new SimpleRegistry<>(registryKey, Lifecycle.experimental(), false) {
@Override @Override
public boolean containsId(Identifier id) { public boolean containsId(Identifier id) {
return true; return true;

View file

@ -14,21 +14,29 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.api.client.texture; package net.fabricmc.fabric.impl.datagen;
import java.util.Set; import java.nio.file.Path;
import net.minecraft.util.Identifier; import org.jetbrains.annotations.ApiStatus;
import net.minecraft.data.DataOutput;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
/** /**
* Implement this interface on a Sprite to declare additional dependencies * Extends {@link DataOutput} to keep track of the {@link FabricDataGenerator} that it originated from.
* that should be processed prior to this sprite.
*
* <p>Best used in conjunction with {@link net.fabricmc.fabric.api.event.client.ClientSpriteRegistryCallback}.
*/ */
public interface DependentSprite { @ApiStatus.Internal
/** public class FabricDataOutput extends DataOutput {
* @return A set of all sprites that should be loaded before this sprite. private final FabricDataGenerator generator;
*/
Set<Identifier> getDependencies(); public FabricDataOutput(FabricDataGenerator generator, Path path) {
super(path);
this.generator = generator;
}
public FabricDataGenerator getGenerator() {
return generator;
}
} }

View file

@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.data.server.AbstractTagProvider; import net.minecraft.data.server.tag.AbstractTagProvider;
import net.minecraft.tag.TagBuilder; import net.minecraft.tag.TagBuilder;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -34,7 +34,7 @@ import net.fabricmc.fabric.impl.datagen.FabricTagBuilder;
@Mixin(AbstractTagProvider.class) @Mixin(AbstractTagProvider.class)
public class AbstractTagProviderMixin { public class AbstractTagProviderMixin {
@Inject(method = "method_27046", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/DataGenerator$PathResolver;resolveJson(Lnet/minecraft/util/Identifier;)Ljava/nio/file/Path;"), locals = LocalCapture.CAPTURE_FAILHARD) @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, Identifier id, TagBuilder builder, CallbackInfo ci, List list, List list2, JsonElement jsonElement) { public void addReplaced(DataWriter dataWriter, Identifier id, TagBuilder builder, CallbackInfo ci, List list, List list2, JsonElement jsonElement) {
if (builder instanceof FabricTagBuilder fabricTagBuilder) { if (builder instanceof FabricTagBuilder fabricTagBuilder) {
jsonElement.getAsJsonObject().addProperty("replace", fabricTagBuilder.fabric_isReplaced()); jsonElement.getAsJsonObject().addProperty("replace", fabricTagBuilder.fabric_isReplaced());

View file

@ -31,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.data.DataGenerator; import net.minecraft.data.DataOutput;
import net.minecraft.data.DataWriter; import net.minecraft.data.DataWriter;
import net.minecraft.data.client.BlockStateModelGenerator; import net.minecraft.data.client.BlockStateModelGenerator;
import net.minecraft.data.client.BlockStateSupplier; import net.minecraft.data.client.BlockStateSupplier;
@ -43,18 +43,21 @@ import net.minecraft.util.registry.Registry;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator; import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider; import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.fabricmc.fabric.impl.datagen.FabricDataOutput;
@Mixin(ModelProvider.class) @Mixin(ModelProvider.class)
public class ModelProviderMixin { public class ModelProviderMixin {
@Unique @Unique
private DataGenerator generator; private FabricDataGenerator generator;
@Unique @Unique
private static final ThreadLocal<DataGenerator> dataGeneratorThreadLocal = new ThreadLocal<>(); private static final ThreadLocal<FabricDataGenerator> dataGeneratorThreadLocal = new ThreadLocal<>();
@Inject(method = "<init>", at = @At("RETURN")) @Inject(method = "<init>", at = @At("RETURN"))
public void init(DataGenerator generator, CallbackInfo ci) { public void init(DataOutput generator, CallbackInfo ci) {
this.generator = generator; if (generator instanceof FabricDataOutput fabricDataOutput) {
this.generator = fabricDataOutput.getGenerator();
}
} }
@Unique @Unique
@ -94,7 +97,9 @@ public class ModelProviderMixin {
@Inject(method = "method_25738", at = @At("HEAD"), cancellable = true) @Inject(method = "method_25738", at = @At("HEAD"), cancellable = true)
private static void filterBlocksForProcessingMod(Map<Block, BlockStateSupplier> map, Block block, CallbackInfoReturnable<Boolean> cir) { private static void filterBlocksForProcessingMod(Map<Block, BlockStateSupplier> map, Block block, CallbackInfoReturnable<Boolean> cir) {
if (dataGeneratorThreadLocal.get() instanceof FabricDataGenerator dataGenerator) { FabricDataGenerator dataGenerator = dataGeneratorThreadLocal.get();
if (dataGenerator != null) {
if (!dataGenerator.isStrictValidationEnabled()) { if (!dataGenerator.isStrictValidationEnabled()) {
cir.setReturnValue(false); cir.setReturnValue(false);
return; return;
@ -109,7 +114,9 @@ public class ModelProviderMixin {
@Inject(method = "method_25741", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/client/ModelIds;getItemModelId(Lnet/minecraft/item/Item;)Lnet/minecraft/util/Identifier;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) @Inject(method = "method_25741", at = @At(value = "INVOKE", target = "Lnet/minecraft/data/client/ModelIds;getItemModelId(Lnet/minecraft/item/Item;)Lnet/minecraft/util/Identifier;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
private static void filterItemsForProcessingMod(Set<Item> set, Map<Identifier, Supplier<JsonElement>> map, Block block, CallbackInfo ci, Item item) { private static void filterItemsForProcessingMod(Set<Item> set, Map<Identifier, Supplier<JsonElement>> map, Block block, CallbackInfo ci, Item item) {
if (dataGeneratorThreadLocal.get() instanceof FabricDataGenerator dataGenerator) { FabricDataGenerator dataGenerator = dataGeneratorThreadLocal.get();
if (dataGenerator != null) {
// Only generate the item model if the block state json was registered // Only generate the item model if the block state json was registered
if (!blockStateMapThreadLocal.get().containsKey(block)) { if (!blockStateMapThreadLocal.get().containsKey(block)) {
ci.cancel(); ci.cancel();

View file

@ -1,25 +1,29 @@
accessWidener v2 named accessWidener v2 named
accessible field net/minecraft/data/server/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataGenerator$PathResolver; accessible field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOutput;
accessible field net/minecraft/data/server/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataGenerator$PathResolver; mutable field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOutput;
accessible field net/minecraft/data/DataGenerator outputPath Ljava/nio/file/Path;
accessible method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder <init> (Lnet/minecraft/tag/TagBuilder;Lnet/minecraft/util/registry/Registry;)V accessible field net/minecraft/data/server/recipe/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
extendable method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder add ([Ljava/lang/Object;)Lnet/minecraft/data/server/AbstractTagProvider$ObjectBuilder; accessible field net/minecraft/data/server/recipe/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
accessible field net/minecraft/data/server/AbstractTagProvider$ObjectBuilder builder Lnet/minecraft/tag/TagBuilder;
accessible field net/minecraft/data/server/AbstractTagProvider$ObjectBuilder registry Lnet/minecraft/util/registry/Registry;
accessible field net/minecraft/data/server/AbstractTagProvider tagBuilders Ljava/util/Map; 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;
accessible field net/minecraft/data/server/BlockLootTableGenerator lootTables Ljava/util/Map; accessible field net/minecraft/data/server/tag/AbstractTagProvider tagBuilders Ljava/util/Map;
accessible field net/minecraft/data/server/loottable/BlockLootTableGenerator lootTables Ljava/util/Map;
extendable method net/minecraft/tag/TagEntry <init> (Lnet/minecraft/util/Identifier;ZZ)V extendable method net/minecraft/tag/TagEntry <init> (Lnet/minecraft/util/Identifier;ZZ)V
accessible field net/minecraft/tag/TagEntry id Lnet/minecraft/util/Identifier; accessible field net/minecraft/tag/TagEntry id Lnet/minecraft/util/Identifier;
accessible field net/minecraft/tag/TagEntry tag Z accessible field net/minecraft/tag/TagEntry tag Z
accessible field net/minecraft/tag/TagEntry required Z accessible field net/minecraft/tag/TagEntry required Z
extendable method net/minecraft/data/DataGenerator$PathResolver <init> (Lnet/minecraft/data/DataGenerator;Lnet/minecraft/data/DataGenerator$OutputType;Ljava/lang/String;)V extendable method net/minecraft/data/DataOutput$PathResolver <init> (Lnet/minecraft/data/DataOutput;Lnet/minecraft/data/DataOutput$OutputType;Ljava/lang/String;)V
accessible field net/minecraft/data/DataGenerator$PathResolver rootPath Ljava/nio/file/Path; accessible field net/minecraft/data/DataOutput$PathResolver rootPath Ljava/nio/file/Path;
accessible field net/minecraft/data/DataGenerator$PathResolver directoryName Ljava/lang/String; accessible field net/minecraft/data/DataOutput$PathResolver directoryName Ljava/lang/String;
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder; transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
@ -29,7 +33,7 @@ transitive-accessible field net/minecraft/data/client/BlockStateModelGenerat
transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;)Lnet/minecraft/data/client/TextureKey; transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;)Lnet/minecraft/data/client/TextureKey;
transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;Lnet/minecraft/data/client/TextureKey;)Lnet/minecraft/data/client/TextureKey; transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;Lnet/minecraft/data/client/TextureKey;)Lnet/minecraft/data/client/TextureKey;
transitive-extendable method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/AbstractTagProvider$ObjectBuilder; transitive-extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
transitive-accessible method net/minecraft/data/client/TexturedModel makeFactory (Ljava/util/function/Function;Lnet/minecraft/data/client/Model;)Lnet/minecraft/data/client/TexturedModel$Factory; transitive-accessible method net/minecraft/data/client/TexturedModel makeFactory (Ljava/util/function/Function;Lnet/minecraft/data/client/Model;)Lnet/minecraft/data/client/TexturedModel$Factory;
@ -38,65 +42,80 @@ transitive-accessible class net/minecraft/data/client/BlockStateModelGenerator
transitive-accessible class net/minecraft/data/client/BlockStateModelGenerator$LogTexturePool transitive-accessible class net/minecraft/data/client/BlockStateModelGenerator$LogTexturePool
transitive-accessible class net/minecraft/data/client/BlockStateModelGenerator$BuiltinModelPool transitive-accessible class net/minecraft/data/client/BlockStateModelGenerator$BuiltinModelPool
transitive-accessible method net/minecraft/data/server/RecipeProvider saveRecipe (Lnet/minecraft/data/DataWriter;Lcom/google/gson/JsonObject;Ljava/nio/file/Path;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider saveRecipeAdvancement (Lnet/minecraft/data/DataWriter;Lnet/minecraft/util/Identifier;Lnet/minecraft/advancement/Advancement$Builder;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider saveRecipeAdvancement (Lnet/minecraft/data/DataWriter;Lcom/google/gson/JsonObject;Ljava/nio/file/Path;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider saveRecipe (Lnet/minecraft/data/DataWriter;Lcom/google/gson/JsonObject;Ljava/nio/file/Path;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider generate (Ljava/util/function/Consumer;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider saveRecipeAdvancement (Lnet/minecraft/data/DataWriter;Lcom/google/gson/JsonObject;Ljava/nio/file/Path;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerSingleOutputShapelessRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider generate (Ljava/util/function/Consumer;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerShapelessRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;I)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider generateFamilies (Ljava/util/function/Consumer;Lnet/minecraft/resource/featuretoggle/FeatureSet;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerSmelting (Ljava/util/function/Consumer;Ljava/util/List;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerSingleOutputShapelessRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBlasting (Ljava/util/function/Consumer;Ljava/util/List;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerShapelessRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;I)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerMultipleOptions (Ljava/util/function/Consumer;Lnet/minecraft/recipe/CookingRecipeSerializer;Ljava/util/List;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;Ljava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerSmelting (Ljava/util/function/Consumer;Ljava/util/List;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerNetheriteUpgradeRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBlasting (Ljava/util/function/Consumer;Ljava/util/List;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerPlanksRecipe2 (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/tag/TagKey;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerMultipleOptions (Ljava/util/function/Consumer;Lnet/minecraft/recipe/RecipeSerializer;Ljava/util/List;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;FILjava/lang/String;Ljava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerPlanksRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/tag/TagKey;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerNetheriteUpgradeRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/Item;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/Item;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBarkBlockRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offer2x2CompactingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBoatRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerPlanksRecipe2 (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/tag/TagKey;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerChestBoatRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerPlanksRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/tag/TagKey;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createTransmutationRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBarkBlockRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createDoorRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBoatRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createFenceRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerChestBoatRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createFenceGateRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createTransmutationRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerPressurePlateRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createDoorRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider createPressurePlateRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createFenceRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerSlabRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createFenceGateRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider createSlabRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerPressurePlateRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createStairsRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createPressurePlateRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider createTrapdoorRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerSlabRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider createSignRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createSlabRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerWoolDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createStairsRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerCarpetRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createTrapdoorRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerCarpetDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createSignRecipe (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBedRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerHangingSignRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBedDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerHangingSignRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;I)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerBannerRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerWoolDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerStainedGlassDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerCarpetRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerStainedGlassPaneRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerCarpetDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerStainedGlassPaneDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBedRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerTerracottaDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBedDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerConcretePowderDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerBannerRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerStonecuttingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerStainedGlassDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerStonecuttingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;I)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerStainedGlassPaneRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerCrackingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerStainedGlassPaneDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerReversibleCompactingRecipes (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerTerracottaDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerReversibleCompactingRecipesWithCompactingRecipeGroup (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerConcretePowderDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerReversibleCompactingRecipesWithReverseRecipeGroup (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerCandleDyeingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerReversibleCompactingRecipes (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerWallRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider generateCookingRecipes (Ljava/util/function/Consumer;Ljava/lang/String;Lnet/minecraft/recipe/CookingRecipeSerializer;I)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getWallRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider offerCookingRecipe (Ljava/util/function/Consumer;Ljava/lang/String;Lnet/minecraft/recipe/CookingRecipeSerializer;ILnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;F)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerPolishedStoneRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider offerWaxingRecipes (Ljava/util/function/Consumer;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createCondensingRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/CraftingRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider generateFamily (Ljava/util/function/Consumer;Lnet/minecraft/data/family/BlockFamily;)V transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerCutCopperRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider getVariantRecipeInput (Lnet/minecraft/data/family/BlockFamily;Lnet/minecraft/data/family/BlockFamily$Variant;)Lnet/minecraft/block/Block; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createCutCopperRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/ShapedRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider requireEnteringFluid (Lnet/minecraft/block/Block;)Lnet/minecraft/advancement/criterion/EnterBlockCriterion$Conditions; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerChiseledBlockRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider conditionsFromItem (Lnet/minecraft/predicate/NumberRange$IntRange;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerMosaicRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider conditionsFromItem (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider createChiseledBlockRecipe (Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/Ingredient;)Lnet/minecraft/data/server/recipe/ShapedRecipeJsonBuilder;
transitive-accessible method net/minecraft/data/server/RecipeProvider conditionsFromTag (Lnet/minecraft/tag/TagKey;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerStonecuttingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider conditionsFromItemPredicates ([Lnet/minecraft/predicate/item/ItemPredicate;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerStonecuttingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;I)V
transitive-accessible method net/minecraft/data/server/RecipeProvider hasItem (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerCrackingRecipe (Ljava/util/function/Consumer;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider getItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerReversibleCompactingRecipes (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider getRecipeName (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerReversibleCompactingRecipesWithCompactingRecipeGroup (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider convertBetween (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerReversibleCompactingRecipesWithReverseRecipeGroup (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider getSmeltingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerReversibleCompactingRecipes (Ljava/util/function/Consumer;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/recipe/book/RecipeCategory;Lnet/minecraft/item/ItemConvertible;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
transitive-accessible method net/minecraft/data/server/RecipeProvider getBlastingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String; transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider generateCookingRecipes (Ljava/util/function/Consumer;Ljava/lang/String;Lnet/minecraft/recipe/RecipeSerializer;I)V
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerFoodCookingRecipe (Ljava/util/function/Consumer;Ljava/lang/String;Lnet/minecraft/recipe/RecipeSerializer;ILnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;F)V
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider offerWaxingRecipes (Ljava/util/function/Consumer;)V
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider generateFamily (Ljava/util/function/Consumer;Lnet/minecraft/data/family/BlockFamily;)V
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getVariantRecipeInput (Lnet/minecraft/data/family/BlockFamily;Lnet/minecraft/data/family/BlockFamily$Variant;)Lnet/minecraft/block/Block;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider requireEnteringFluid (Lnet/minecraft/block/Block;)Lnet/minecraft/advancement/criterion/EnterBlockCriterion$Conditions;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItem (Lnet/minecraft/predicate/NumberRange$IntRange;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItem (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromTag (Lnet/minecraft/tag/TagKey;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider conditionsFromItemPredicates ([Lnet/minecraft/predicate/item/ItemPredicate;)Lnet/minecraft/advancement/criterion/InventoryChangedCriterion$Conditions;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider hasItem (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getRecipeName (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider convertBetween (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/recipe/RecipeProvider getSmeltingItemPath (Lnet/minecraft/item/ItemConvertible;)Ljava/lang/String;
transitive-accessible method net/minecraft/data/server/recipe/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 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 createMudBrickState (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 createMudBrickState (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 createDeepslateState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/data/client/TextureMap;Ljava/util/function/BiConsumer;)Lnet/minecraft/data/client/BlockStateSupplier;
@ -119,9 +138,10 @@ transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator
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 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/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateVariantMap$QuadrupleProperty; 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 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 createCustomFenceBlockState (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/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 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 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; 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;Z)Lnet/minecraft/data/client/BlockStateSupplier;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator createStairsBlockState (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 createStairsBlockState (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 createOrientableTrapdoorBlockState (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 createOrientableTrapdoorBlockState (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 createTrapdoorBlockState (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 createTrapdoorBlockState (Lnet/minecraft/block/Block;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;Lnet/minecraft/util/Identifier;)Lnet/minecraft/data/client/BlockStateSupplier;
@ -205,47 +225,51 @@ transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerRoots (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerRoots (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator addJigsawOrientationToVariant (Lnet/minecraft/block/enums/JigsawOrientation;Lnet/minecraft/data/client/BlockStateVariant;)Lnet/minecraft/data/client/BlockStateVariant; transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator addJigsawOrientationToVariant (Lnet/minecraft/block/enums/JigsawOrientation;Lnet/minecraft/data/client/BlockStateVariant;)Lnet/minecraft/data/client/BlockStateVariant;
transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerCandle (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/data/client/BlockStateModelGenerator registerCandle (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator applyExplosionDecay (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/function/LootFunctionConsumingBuilder;)Lnet/minecraft/loot/function/LootFunctionConsumingBuilder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator applyExplosionDecay (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/function/LootFunctionConsumingBuilder;)Lnet/minecraft/loot/function/LootFunctionConsumingBuilder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator addSurvivesExplosionCondition (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/condition/LootConditionConsumingBuilder;)Lnet/minecraft/loot/condition/LootConditionConsumingBuilder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addSurvivesExplosionCondition (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/condition/LootConditionConsumingBuilder;)Lnet/minecraft/loot/condition/LootConditionConsumingBuilder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator drops (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/loot/condition/LootCondition$Builder;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/loot/condition/LootCondition$Builder;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithShears (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithShears (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithSilkTouchOrShears (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithSilkTouchOrShears (Lnet/minecraft/block/Block;Lnet/minecraft/loot/entry/LootPoolEntry$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator drops (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/provider/number/LootNumberProvider;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator drops (Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/provider/number/LootNumberProvider;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/provider/number/LootNumberProvider;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator drops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;Lnet/minecraft/loot/provider/number/LootNumberProvider;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithSilkTouch (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator pottedPlantDrops (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator pottedPlantDrops (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator slabDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator slabDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithProperty (Lnet/minecraft/block/Block;Lnet/minecraft/state/property/Property;Ljava/lang/Comparable;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithProperty (Lnet/minecraft/block/Block;Lnet/minecraft/state/property/Property;Ljava/lang/Comparable;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator nameableContainerDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator nameableContainerDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator shulkerBoxDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator shulkerBoxDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator copperOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator copperOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator lapisOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator lapisOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator redstoneOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator redstoneOreDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator bannerDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator bannerDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator beeNestDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator beeNestDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator beehiveDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator beehiveDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator glowBerryDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator glowBerryDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator oreDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator oreDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator mushroomBlockDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator mushroomBlockDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator grassDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator grassDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator dropsWithShears (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator cropStemDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator multifaceGrowthDrops (Lnet/minecraft/block/Block;Lnet/minecraft/loot/condition/LootCondition$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator attachedCropStemDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator leavesDrops (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;[F)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator dropsWithShears (Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator oakLeavesDrops (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;[F)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator multifaceGrowthDrops (Lnet/minecraft/block/Block;Lnet/minecraft/loot/condition/LootCondition$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator mangroveLeavesDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator leavesDrop (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;[F)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator cropDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/loot/condition/LootCondition$Builder;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator oakLeavesDrop (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;[F)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator seagrassDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator mangroveLeavesDrop (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator tallGrassDrops (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator cropDrops (Lnet/minecraft/block/Block;Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/loot/condition/LootCondition$Builder;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator candleDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator seagrassDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator candleCakeDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator tallGrassDrops (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator generate ()V
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator candleDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addVinePlantDrop (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator candleCakeDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder; transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator doorDrops (Lnet/minecraft/block/Block;)Lnet/minecraft/loot/LootTable$Builder;
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator addVinePlantDrop (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addPottedPlantDrops (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;Ljava/util/function/Function;)V transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDropWithSilkTouch (Lnet/minecraft/block/Block;Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;Lnet/minecraft/loot/LootTable$Builder;)V transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;Lnet/minecraft/item/ItemConvertible;)V
transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDropWithSilkTouch (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;)V
transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;Ljava/util/function/Function;)V
transitive-accessible method net/minecraft/data/server/loottable/BlockLootTableGenerator addDrop (Lnet/minecraft/block/Block;Lnet/minecraft/loot/LootTable$Builder;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Ljava/lang/String;Lnet/minecraft/data/client/Model;)V transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Ljava/lang/String;Lnet/minecraft/data/client/Model;)V
transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V transitive-accessible method net/minecraft/data/client/ItemModelGenerator register (Lnet/minecraft/item/Item;Lnet/minecraft/item/Item;Lnet/minecraft/data/client/Model;)V

View file

@ -5,7 +5,6 @@
"mixins": [ "mixins": [
"AbstractTagProviderMixin", "AbstractTagProviderMixin",
"ModelProviderMixin", "ModelProviderMixin",
"DynamicRegistryManagerAccessor",
"TagBuilderMixin" "TagBuilderMixin"
], ],
"server": [ "server": [

View file

@ -16,21 +16,22 @@
package net.fabricmc.fabric.test.datagen; package net.fabricmc.fabric.test.datagen;
import java.util.Objects; import java.util.ArrayList;
import java.util.List;
import net.minecraft.block.AbstractBlock; import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Material; import net.minecraft.block.Material;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
public class DataGeneratorTestContent implements ModInitializer { public class DataGeneratorTestContent implements ModInitializer {
public static final String MOD_ID = "fabric-data-gen-api-v1-testmod"; public static final String MOD_ID = "fabric-data-gen-api-v1-testmod";
@ -38,11 +39,11 @@ public class DataGeneratorTestContent implements ModInitializer {
public static Block SIMPLE_BLOCK; public static Block SIMPLE_BLOCK;
public static Block BLOCK_WITHOUT_ITEM; public static Block BLOCK_WITHOUT_ITEM;
public static Block BLOCK_WITHOUT_LOOT_TABLE; public static Block BLOCK_WITHOUT_LOOT_TABLE;
public static ItemGroup SIMPLE_ITEM_GROUP;
public static final SimpleItemGroup SIMPLE_ITEM_GROUP = new SimpleItemGroup();
@Override @Override
public void onInitialize() { public void onInitialize() {
SIMPLE_ITEM_GROUP = FabricItemGroupBuilder.build(new Identifier(MOD_ID, "default"), () -> new ItemStack(Items.BONE));
SIMPLE_BLOCK = createBlock("simple_block", true); SIMPLE_BLOCK = createBlock("simple_block", true);
BLOCK_WITHOUT_ITEM = createBlock("block_without_item", false); BLOCK_WITHOUT_ITEM = createBlock("block_without_item", false);
BLOCK_WITHOUT_LOOT_TABLE = createBlock("block_without_loot_table", false); BLOCK_WITHOUT_LOOT_TABLE = createBlock("block_without_loot_table", false);
@ -53,11 +54,28 @@ public class DataGeneratorTestContent implements ModInitializer {
Block block = Registry.register(Registry.BLOCK, identifier, new Block(AbstractBlock.Settings.of(Material.STONE))); Block block = Registry.register(Registry.BLOCK, identifier, new Block(AbstractBlock.Settings.of(Material.STONE)));
if (hasItem) { if (hasItem) {
Registry.register(Registry.ITEM, identifier, new BlockItem(block, new Item.Settings().group(ItemGroup.MISC))); Item item = Registry.register(Registry.ITEM, identifier, new BlockItem(block, new Item.Settings()));
SIMPLE_ITEM_GROUP.items.add(new ItemStack(item));
Objects.requireNonNull(block.asItem().getGroup());
} }
return block; return block;
} }
private static class SimpleItemGroup extends FabricItemGroup {
public List<ItemStack> items = new ArrayList<>();
SimpleItemGroup() {
super(new Identifier(MOD_ID, "simple"));
}
@Override
public ItemStack createIcon() {
return new ItemStack(Items.BONE);
}
@Override
protected void addItems(FeatureSet featureSet, Entries entries) {
entries.addAll(items);
}
}
} }

View file

@ -47,6 +47,7 @@ import net.minecraft.loot.LootTables;
import net.minecraft.loot.context.LootContextTypes; import net.minecraft.loot.context.LootContextTypes;
import net.minecraft.loot.entry.ItemEntry; import net.minecraft.loot.entry.ItemEntry;
import net.minecraft.loot.provider.number.ConstantLootNumberProvider; import net.minecraft.loot.provider.number.ConstantLootNumberProvider;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.tag.BlockTags; import net.minecraft.tag.BlockTags;
import net.minecraft.tag.ItemTags; import net.minecraft.tag.ItemTags;
import net.minecraft.tag.TagKey; import net.minecraft.tag.TagKey;
@ -118,7 +119,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
} }
@Override @Override
protected void generateRecipes(Consumer<RecipeJsonProvider> exporter) { public void generate(Consumer<RecipeJsonProvider> exporter) {
offerPlanksRecipe2(exporter, SIMPLE_BLOCK, ItemTags.ACACIA_LOGS); offerPlanksRecipe2(exporter, SIMPLE_BLOCK, ItemTags.ACACIA_LOGS);
} }
} }
@ -174,9 +175,9 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
} }
@Override @Override
protected void generateRecipes(Consumer<RecipeJsonProvider> exporter) { public void generate(Consumer<RecipeJsonProvider> exporter) {
ShapelessRecipeJsonBuilder.create(Items.GOLD_INGOT).input(Items.DIRT).criterion("has_dirt", conditionsFromItem(Items.DIRT)).offerTo(withConditions(exporter, NEVER_LOADED)); ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.GOLD_INGOT).input(Items.DIRT).criterion("has_dirt", conditionsFromItem(Items.DIRT)).offerTo(withConditions(exporter, NEVER_LOADED));
ShapelessRecipeJsonBuilder.create(Items.DIAMOND).input(Items.STICK).criterion("has_stick", conditionsFromItem(Items.STICK)).offerTo(withConditions(exporter, ALWAYS_LOADED)); ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, Items.DIAMOND).input(Items.STICK).criterion("has_stick", conditionsFromItem(Items.STICK)).offerTo(withConditions(exporter, ALWAYS_LOADED));
} }
} }
@ -278,7 +279,7 @@ public class DataGeneratorTestEntrypoint implements DataGeneratorEntrypoint {
} }
@Override @Override
protected void generateBlockLootTables() { public void generate() {
addDrop(SIMPLE_BLOCK); addDrop(SIMPLE_BLOCK);
addDrop(BLOCK_WITHOUT_ITEM, drops(SIMPLE_BLOCK)); addDrop(BLOCK_WITHOUT_ITEM, drops(SIMPLE_BLOCK));

View file

@ -1,25 +1,28 @@
accessWidener v2 named accessWidener v2 named
accessible field net/minecraft/data/server/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataGenerator$PathResolver; accessible field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOutput;
accessible field net/minecraft/data/server/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataGenerator$PathResolver; mutable field net/minecraft/data/DataGenerator output Lnet/minecraft/data/DataOutput;
accessible method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder <init> (Lnet/minecraft/tag/TagBuilder;Lnet/minecraft/util/registry/Registry;)V accessible field net/minecraft/data/server/recipe/RecipeProvider recipesPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
extendable method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder add ([Ljava/lang/Object;)Lnet/minecraft/data/server/AbstractTagProvider$ObjectBuilder; accessible field net/minecraft/data/server/recipe/RecipeProvider advancementsPathResolver Lnet/minecraft/data/DataOutput$PathResolver;
accessible field net/minecraft/data/server/AbstractTagProvider$ObjectBuilder builder Lnet/minecraft/tag/TagBuilder;
accessible field net/minecraft/data/server/AbstractTagProvider$ObjectBuilder registry Lnet/minecraft/util/registry/Registry;
accessible field net/minecraft/data/server/AbstractTagProvider tagBuilders Ljava/util/Map; 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;
accessible field net/minecraft/data/server/BlockLootTableGenerator lootTables Ljava/util/Map; accessible field net/minecraft/data/server/tag/AbstractTagProvider tagBuilders Ljava/util/Map;
accessible field net/minecraft/data/server/loottable/BlockLootTableGenerator lootTables Ljava/util/Map;
extendable method net/minecraft/tag/TagEntry <init> (Lnet/minecraft/util/Identifier;ZZ)V extendable method net/minecraft/tag/TagEntry <init> (Lnet/minecraft/util/Identifier;ZZ)V
accessible field net/minecraft/tag/TagEntry id Lnet/minecraft/util/Identifier; accessible field net/minecraft/tag/TagEntry id Lnet/minecraft/util/Identifier;
accessible field net/minecraft/tag/TagEntry tag Z accessible field net/minecraft/tag/TagEntry tag Z
accessible field net/minecraft/tag/TagEntry required Z accessible field net/minecraft/tag/TagEntry required Z
extendable method net/minecraft/data/DataGenerator$PathResolver <init> (Lnet/minecraft/data/DataGenerator;Lnet/minecraft/data/DataGenerator$OutputType;Ljava/lang/String;)V extendable method net/minecraft/data/DataOutput$PathResolver <init> (Lnet/minecraft/data/DataOutput;Lnet/minecraft/data/DataOutput$OutputType;Ljava/lang/String;)V
accessible field net/minecraft/data/DataGenerator$PathResolver rootPath Ljava/nio/file/Path; accessible field net/minecraft/data/DataOutput$PathResolver rootPath Ljava/nio/file/Path;
accessible field net/minecraft/data/DataGenerator$PathResolver directoryName Ljava/lang/String; accessible field net/minecraft/data/DataOutput$PathResolver directoryName Ljava/lang/String;
transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder; transitive-accessible method net/minecraft/data/family/BlockFamilies register (Lnet/minecraft/block/Block;)Lnet/minecraft/data/family/BlockFamily$Builder;
@ -29,7 +32,7 @@ transitive-accessible field net/minecraft/data/client/BlockStateModelGenerat
transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;)Lnet/minecraft/data/client/TextureKey; transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;)Lnet/minecraft/data/client/TextureKey;
transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;Lnet/minecraft/data/client/TextureKey;)Lnet/minecraft/data/client/TextureKey; transitive-accessible method net/minecraft/data/client/TextureKey of (Ljava/lang/String;Lnet/minecraft/data/client/TextureKey;)Lnet/minecraft/data/client/TextureKey;
transitive-extendable method net/minecraft/data/server/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/AbstractTagProvider$ObjectBuilder; transitive-extendable method net/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder add ([Lnet/minecraft/util/registry/RegistryKey;)Lnet/minecraft/data/server/tag/AbstractTagProvider$ObjectBuilder;
transitive-accessible method net/minecraft/data/client/TexturedModel makeFactory (Ljava/util/function/Function;Lnet/minecraft/data/client/Model;)Lnet/minecraft/data/client/TexturedModel$Factory; transitive-accessible method net/minecraft/data/client/TexturedModel makeFactory (Ljava/util/function/Function;Lnet/minecraft/data/client/Model;)Lnet/minecraft/data/client/TexturedModel$Factory;

View file

@ -1,93 +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.dimension;
import com.mojang.serialization.DynamicOps;
import com.mojang.serialization.Lifecycle;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.nbt.NbtElement;
import net.minecraft.resource.DataPackSettings;
import net.minecraft.server.Main;
import net.minecraft.util.registry.DynamicRegistryManager;
import net.minecraft.world.gen.GeneratorOptions;
import net.minecraft.world.level.LevelInfo;
import net.minecraft.world.level.LevelProperties;
import net.minecraft.world.level.storage.LevelStorage;
/**
* This Mixin aims to solve a Minecraft Vanilla bug where datapacks are ignored during creation of the
* initial LevelProperties when a dedicated server creates a completely new level.
*
* <p>This also includes the datapacks of loaded Fabric mods, and results in modded dimensions only
* being available after restarting the server, once the world has been created.
*
* <p>This Mixin aims to solve this problem by saving and loading the level.dat file once, after
* a new set of level properties is created. This will apply the same logic as reloading the
* level.dat after a restart, now including all datapack dimensions.
*
* <p>See https://bugs.mojang.com/browse/MC-195468 for a related bug report.
*
* <p>TODO: Retest if this bug still occurs without this Mixin by launching a dedicated server with the
* dimension testmod, and no world directory. If the dimension is available (i.e. in /execute in, or via
* the testmod's commands), then the bug is fixed and this Mixin can be removed.
*/
@Mixin(value = Main.class)
public class MainMixin {
@Unique
private static LevelStorage.Session session;
@Unique
private static DynamicRegistryManager.Mutable drm;
@Unique
private static DynamicOps<NbtElement> ops;
@ModifyVariable(method = "main", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/storage/LevelStorage;createSession(Ljava/lang/String;)Lnet/minecraft/world/level/storage/LevelStorage$Session;"))
private static LevelStorage.Session captureSession(LevelStorage.Session value) {
session = value;
return value;
}
@ModifyVariable(method = "method_43613", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/registry/DynamicRegistryManager;createAndLoad()Lnet/minecraft/util/registry/DynamicRegistryManager$Mutable;"))
private static DynamicRegistryManager.Mutable captureDrm(DynamicRegistryManager.Mutable value) {
drm = value;
return value;
}
// The value is stored as DynamicOps instead of RegistryOps in the bytecode
@ModifyVariable(method = "method_43613", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/dynamic/RegistryOps;ofLoaded(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/util/registry/DynamicRegistryManager$Mutable;Lnet/minecraft/resource/ResourceManager;)Lnet/minecraft/util/dynamic/RegistryOps;"))
private static DynamicOps<NbtElement> captureOps(DynamicOps<NbtElement> value) {
ops = value;
return value;
}
@Redirect(method = "method_43613", at = @At(value = "NEW", target = "net/minecraft/world/level/LevelProperties"))
private static LevelProperties onCreateNewLevelProperties(LevelInfo levelInfo, GeneratorOptions generatorOptions, Lifecycle lifecycle) {
DataPackSettings dataPackSettings = levelInfo.getDataPackSettings();
// Save the level.dat file
session.backupLevelDataFile(drm, new LevelProperties(levelInfo, generatorOptions, lifecycle));
// And reload it again, and replace the actual level properties with it
return (LevelProperties) session.readLevelProperties(ops, dataPackSettings, drm.getRegistryLifecycle());
}
}

View file

@ -4,8 +4,7 @@
"compatibilityLevel": "JAVA_16", "compatibilityLevel": "JAVA_16",
"mixins": [ "mixins": [
"EntityMixin", "EntityMixin",
"LevelStorageMixin", "LevelStorageMixin"
"MainMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View file

@ -30,14 +30,13 @@ import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.network.encryption.PlayerPublicKey;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket; import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Mixin(ClientPlayerEntity.class) @Mixin(ClientPlayerEntity.class)
abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity { abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity {
ClientPlayerEntityMixin(ClientWorld world, GameProfile profile, PlayerPublicKey playerPublicKey) { ClientPlayerEntityMixin(ClientWorld world, GameProfile profile) {
super(world, profile, playerPublicKey); super(world, profile);
throw new AssertionError(); throw new AssertionError();
} }

View file

@ -19,12 +19,11 @@ package net.fabricmc.fabric.test.entity.event;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem;
import net.minecraft.item.ArmorMaterials; import net.minecraft.item.ArmorMaterials;
import net.minecraft.item.ItemGroup;
import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem; import net.fabricmc.fabric.api.entity.event.v1.FabricElytraItem;
public class DiamondElytraItem extends ArmorItem implements FabricElytraItem { public class DiamondElytraItem extends ArmorItem implements FabricElytraItem {
public DiamondElytraItem() { public DiamondElytraItem() {
super(ArmorMaterials.DIAMOND, EquipmentSlot.CHEST, new Settings().maxCount(1).group(ItemGroup.COMBAT)); super(ArmorMaterials.DIAMOND, EquipmentSlot.CHEST, new Settings().maxCount(1));
} }
} }

View file

@ -27,7 +27,6 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
@ -55,7 +54,7 @@ public final class EntityEventTests implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
Registry.register(Registry.BLOCK, new Identifier("fabric-entity-events-v1-testmod", "test_bed"), TEST_BED); Registry.register(Registry.BLOCK, new Identifier("fabric-entity-events-v1-testmod", "test_bed"), TEST_BED);
Registry.register(Registry.ITEM, new Identifier("fabric-entity-events-v1-testmod", "test_bed"), new BlockItem(TEST_BED, new Item.Settings().group(ItemGroup.DECORATIONS))); Registry.register(Registry.ITEM, new Identifier("fabric-entity-events-v1-testmod", "test_bed"), new BlockItem(TEST_BED, new Item.Settings()));
Registry.register(Registry.ITEM, new Identifier("fabric-entity-events-v1-testmod", "diamond_elytra"), DIAMOND_ELYTRA); Registry.register(Registry.ITEM, new Identifier("fabric-entity-events-v1-testmod", "diamond_elytra"), DIAMOND_ELYTRA);
ServerEntityCombatEvents.AFTER_KILLED_OTHER_ENTITY.register((world, entity, killed) -> { ServerEntityCombatEvents.AFTER_KILLED_OTHER_ENTITY.register((world, entity, killed) -> {

View file

@ -47,7 +47,7 @@ public class MainMixin {
} }
// Inject after resourcePackManager is stored // Inject after resourcePackManager is stored
@Inject(method = "main", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.BY, by = 2, target = "Lnet/minecraft/resource/ResourcePackManager;<init>(Lnet/minecraft/resource/ResourceType;[Lnet/minecraft/resource/ResourcePackProvider;)V")) @Inject(method = "main", cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD, at = @At(value = "INVOKE", shift = At.Shift.BY, by = 2, target = "Lnet/minecraft/resource/VanillaDataPackProvider;createManager(Ljava/nio/file/Path;)Lnet/minecraft/resource/ResourcePackManager;"))
private static void main(String[] args, CallbackInfo info, OptionParser optionParser, OptionSpec optionSpec, OptionSpec optionSpec2, OptionSpec optionSpec3, OptionSpec optionSpec4, OptionSpec optionSpec5, OptionSpec optionSpec6, OptionSpec optionSpec7, OptionSpec optionSpec8, OptionSpec optionSpec9, OptionSpec optionSpec10, OptionSpec optionSpec11, OptionSpec optionSpec12, OptionSpec optionSpec13, OptionSpec optionSpec14, OptionSpec optionSpec15, OptionSet optionSet, Path path, ServerPropertiesLoader serverPropertiesLoader, Path path2, EulaReader eulaReader, File file, ApiServices lv, String string, LevelStorage levelStorage, LevelStorage.Session session, LevelSummary levelSummary, boolean bl, ResourcePackManager resourcePackManager) { private static void main(String[] args, CallbackInfo info, OptionParser optionParser, OptionSpec optionSpec, OptionSpec optionSpec2, OptionSpec optionSpec3, OptionSpec optionSpec4, OptionSpec optionSpec5, OptionSpec optionSpec6, OptionSpec optionSpec7, OptionSpec optionSpec8, OptionSpec optionSpec9, OptionSpec optionSpec10, OptionSpec optionSpec11, OptionSpec optionSpec12, OptionSpec optionSpec13, OptionSpec optionSpec14, OptionSpec optionSpec15, OptionSet optionSet, Path path, ServerPropertiesLoader serverPropertiesLoader, Path path2, EulaReader eulaReader, File file, ApiServices lv, String string, LevelStorage levelStorage, LevelStorage.Session session, LevelSummary levelSummary, boolean bl, ResourcePackManager resourcePackManager) {
if (FabricGameTestHelper.ENABLED) { if (FabricGameTestHelper.ENABLED) {
FabricGameTestHelper.runHeadlessServer(session, resourcePackManager); FabricGameTestHelper.runHeadlessServer(session, resourcePackManager);

View file

@ -18,7 +18,6 @@ package net.fabricmc.fabric.api.item.v1;
import net.minecraft.item.FoodComponent; import net.minecraft.item.FoodComponent;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.Rarity; import net.minecraft.util.Rarity;
@ -46,6 +45,7 @@ public class FabricItemSettings extends Item.Settings {
/** /**
* Sets the custom damage handler of the item. * Sets the custom damage handler of the item.
* Note that this is only called on an ItemStack if {@link ItemStack#isDamageable()} returns true. * Note that this is only called on an ItemStack if {@link ItemStack#isDamageable()} returns true.
*
* @see CustomDamageHandler * @see CustomDamageHandler
*/ */
public FabricItemSettings customDamage(CustomDamageHandler handler) { public FabricItemSettings customDamage(CustomDamageHandler handler) {
@ -85,12 +85,6 @@ public class FabricItemSettings extends Item.Settings {
return this; return this;
} }
@Override
public FabricItemSettings group(ItemGroup group) {
super.group(group);
return this;
}
@Override @Override
public FabricItemSettings rarity(Rarity rarity) { public FabricItemSettings rarity(Rarity rarity) {
super.rarity(rarity); super.rarity(rarity);

View file

@ -18,7 +18,6 @@ package net.fabricmc.fabric.test.item;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.Registry;
@ -29,7 +28,7 @@ public class FabricItemSettingsTests implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
// Registers an item with a custom equipment slot. // Registers an item with a custom equipment slot.
Item testItem = new Item(new FabricItemSettings().group(ItemGroup.MISC).equipmentSlot(stack -> EquipmentSlot.CHEST)); Item testItem = new Item(new FabricItemSettings().equipmentSlot(stack -> EquipmentSlot.CHEST));
Registry.register(Registry.ITEM, new Identifier("fabric-item-api-v1-testmod", "test_item"), testItem); Registry.register(Registry.ITEM, new Identifier("fabric-item-api-v1-testmod", "test_item"), testItem);
} }
} }

View file

@ -27,7 +27,6 @@ import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
@ -40,7 +39,7 @@ public class UpdatingItem extends Item {
private final boolean allowUpdateAnimation; private final boolean allowUpdateAnimation;
public UpdatingItem(boolean allowUpdateAnimation) { public UpdatingItem(boolean allowUpdateAnimation) {
super(new Settings().group(ItemGroup.MISC)); super(new Settings());
this.allowUpdateAnimation = allowUpdateAnimation; this.allowUpdateAnimation = allowUpdateAnimation;
} }
@ -48,7 +47,7 @@ public class UpdatingItem extends Item {
public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) { public void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) {
if (!world.isClient) { if (!world.isClient) {
NbtCompound tag = stack.getOrCreateNbt(); NbtCompound tag = stack.getOrCreateNbt();
tag.putLong("ticks", tag.getLong("ticks")+1); tag.putLong("ticks", tag.getLong("ticks") + 1);
} }
} }

View file

@ -0,0 +1,11 @@
archivesBaseName = "fabric-item-group-api-v1"
version = getSubprojectVersion(project)
moduleDependencies(project, [
'fabric-api-base',
'fabric-resource-loader-v0'
])
loom {
accessWidenerPath = file('src/main/resources/fabric-item-group-api-v1.accesswidener')
}

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.impl.item.group; package net.fabricmc.fabric.impl.itemgroup;
public interface CreativeGuiExtensions { public interface CreativeGuiExtensions {
void fabric_nextPage(); void fabric_nextPage();

View file

@ -14,9 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.impl.item.group; package net.fabricmc.fabric.impl.itemgroup;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -26,23 +25,18 @@ import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class FabricCreativeGuiComponents { public class FabricCreativeGuiComponents {
private static final Identifier BUTTON_TEX = new Identifier("fabric", "textures/gui/creative_buttons.png"); private static final Identifier BUTTON_TEX = new Identifier("fabric", "textures/gui/creative_buttons.png");
public static final Set<ItemGroup> COMMON_GROUPS = new HashSet<>(); public static final Set<ItemGroup> COMMON_GROUPS = Set.of(ItemGroups.SEARCH, ItemGroups.INVENTORY, ItemGroups.HOTBAR);
static {
COMMON_GROUPS.add(ItemGroup.SEARCH);
COMMON_GROUPS.add(ItemGroup.INVENTORY);
COMMON_GROUPS.add(ItemGroup.HOTBAR);
}
public static class ItemGroupButtonWidget extends ButtonWidget { public static class ItemGroupButtonWidget extends ButtonWidget {
CreativeGuiExtensions extensions; final CreativeGuiExtensions extensions;
CreativeInventoryScreen gui; final CreativeInventoryScreen gui;
Type type; final Type type;
public ItemGroupButtonWidget(int x, int y, Type type, CreativeGuiExtensions extensions) { public ItemGroupButtonWidget(int x, int y, Type type, CreativeGuiExtensions extensions) {
super(x, y, 11, 10, type.text, (bw) -> type.clickConsumer.accept(extensions)); super(x, y, 11, 10, type.text, (bw) -> type.clickConsumer.accept(extensions));
@ -66,7 +60,7 @@ public class FabricCreativeGuiComponents {
this.drawTexture(matrixStack, this.x, this.y, u + (type == Type.NEXT ? 11 : 0), v, 11, 10); this.drawTexture(matrixStack, this.x, this.y, u + (type == Type.NEXT ? 11 : 0), v, 11, 10);
if (this.hovered) { if (this.hovered) {
int pageCount = (int) Math.ceil((ItemGroup.GROUPS.length - COMMON_GROUPS.size()) / 9D); int pageCount = (int) Math.ceil((ItemGroups.GROUPS.length - COMMON_GROUPS.size()) / 9D);
gui.renderTooltip(matrixStack, Text.translatable("fabric.gui.creativeTabPage", extensions.fabric_currentPage() + 1, pageCount), mouseX, mouseY); gui.renderTooltip(matrixStack, Text.translatable("fabric.gui.creativeTabPage", extensions.fabric_currentPage() + 1, pageCount), mouseX, mouseY);
} }
} }
@ -77,8 +71,8 @@ public class FabricCreativeGuiComponents {
NEXT(Text.literal(">"), CreativeGuiExtensions::fabric_nextPage), NEXT(Text.literal(">"), CreativeGuiExtensions::fabric_nextPage),
PREVIOUS(Text.literal("<"), CreativeGuiExtensions::fabric_previousPage); PREVIOUS(Text.literal("<"), CreativeGuiExtensions::fabric_previousPage);
Text text; final Text text;
Consumer<CreativeGuiExtensions> clickConsumer; final Consumer<CreativeGuiExtensions> clickConsumer;
Type(Text text, Consumer<CreativeGuiExtensions> clickConsumer) { Type(Text text, Consumer<CreativeGuiExtensions> clickConsumer) {
this.text = text; this.text = text;

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.mixin.item.group.client; package net.fabricmc.fabric.mixin.itemgroup.client;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -26,18 +26,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen; import net.minecraft.client.gui.screen.ingame.AbstractInventoryScreen;
import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen; import net.minecraft.client.gui.screen.ingame.CreativeInventoryScreen;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.fabricmc.fabric.impl.item.group.CreativeGuiExtensions; import net.fabricmc.fabric.impl.itemgroup.CreativeGuiExtensions;
import net.fabricmc.fabric.impl.item.group.FabricCreativeGuiComponents; import net.fabricmc.fabric.impl.itemgroup.FabricCreativeGuiComponents;
@Mixin(CreativeInventoryScreen.class) @Mixin(CreativeInventoryScreen.class)
public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScreen implements CreativeGuiExtensions { public abstract class CreativeInventoryScreenMixin<T extends ScreenHandler> extends AbstractInventoryScreen<T> implements CreativeGuiExtensions {
public CreativeInventoryScreenMixin(ScreenHandler container_1, PlayerInventory playerInventory_1, Text textComponent_1) { public CreativeInventoryScreenMixin(T screenHandler, PlayerInventory playerInventory, Text text) {
super(container_1, playerInventory_1, textComponent_1); super(screenHandler, playerInventory, text);
} }
@Shadow @Shadow
@ -50,14 +51,11 @@ public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScre
private static int fabric_currentPage = 0; private static int fabric_currentPage = 0;
private int fabric_getPageOffset(int page) { private int fabric_getPageOffset(int page) {
switch (page) { return switch (page) {
case 0: case 0 -> 0;
return 0; case 1 -> 12;
case 1: default -> 12 + ((12 - FabricCreativeGuiComponents.COMMON_GROUPS.size()) * (page - 1));
return 12; };
default:
return 12 + ((12 - FabricCreativeGuiComponents.COMMON_GROUPS.size()) * (page - 1));
}
} }
private int fabric_getOffsetPage(int offset) { private int fabric_getOffsetPage(int offset) {
@ -70,7 +68,7 @@ public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScre
@Override @Override
public void fabric_nextPage() { public void fabric_nextPage() {
if (fabric_getPageOffset(fabric_currentPage + 1) >= ItemGroup.GROUPS.length) { if (fabric_getPageOffset(fabric_currentPage + 1) >= ItemGroups.GROUPS.length) {
return; return;
} }
@ -90,13 +88,13 @@ public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScre
@Override @Override
public boolean fabric_isButtonVisible(FabricCreativeGuiComponents.Type type) { public boolean fabric_isButtonVisible(FabricCreativeGuiComponents.Type type) {
return ItemGroup.GROUPS.length > 12; return ItemGroups.GROUPS.length > 12;
} }
@Override @Override
public boolean fabric_isButtonEnabled(FabricCreativeGuiComponents.Type type) { public boolean fabric_isButtonEnabled(FabricCreativeGuiComponents.Type type) {
if (type == FabricCreativeGuiComponents.Type.NEXT) { if (type == FabricCreativeGuiComponents.Type.NEXT) {
return !(fabric_getPageOffset(fabric_currentPage + 1) >= ItemGroup.GROUPS.length); return !(fabric_getPageOffset(fabric_currentPage + 1) >= ItemGroups.GROUPS.length);
} }
if (type == FabricCreativeGuiComponents.Type.PREVIOUS) { if (type == FabricCreativeGuiComponents.Type.PREVIOUS) {
@ -112,7 +110,7 @@ public abstract class CreativeInventoryScreenMixin extends AbstractInventoryScre
int curPos = getSelectedTab(); int curPos = getSelectedTab();
if (curPos < minPos || curPos > maxPos) { if (curPos < minPos || curPos > maxPos) {
setSelectedTab(ItemGroup.GROUPS[fabric_getPageOffset(fabric_currentPage)]); setSelectedTab(ItemGroups.GROUPS[fabric_getPageOffset(fabric_currentPage)]);
} }
} }

View file

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.mixin.item.group.client; package net.fabricmc.fabric.mixin.itemgroup.client;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
@ -24,7 +24,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.fabricmc.fabric.impl.item.group.FabricCreativeGuiComponents; import net.fabricmc.fabric.impl.itemgroup.FabricCreativeGuiComponents;
@Mixin(ItemGroup.class) @Mixin(ItemGroup.class)
public abstract class ItemGroupMixin { public abstract class ItemGroupMixin {

View file

@ -1,7 +1,7 @@
{ {
"required": true, "required": true,
"package": "net.fabricmc.fabric.mixin.item.group.client", "package": "net.fabricmc.fabric.mixin.itemgroup.client",
"compatibilityLevel": "JAVA_16", "compatibilityLevel": "JAVA_17",
"client": [ "client": [
"ItemGroupMixin", "ItemGroupMixin",
"CreativeInventoryScreenMixin" "CreativeInventoryScreenMixin"

View file

@ -0,0 +1,65 @@
/*
* 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.itemgroup.v1;
import java.util.Objects;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.itemgroup.ItemGroupHelper;
/**
* Extend this abstract class to create a new {@link ItemGroup} for a mod.
*
* <p>Each new instance of this class is automatically appended to {@link ItemGroups#GROUPS}.
*
* <p>Example:
* <pre>{@code
* public static final ItemGroup ITEM_GROUP = new FabricItemGroup(new Identifier("modid", "test_group")) {
* @Override
* public ItemStack createIcon() {
* return new ItemStack(Items.DIAMOND);
* }
*
* @Override
* protected void addItems(FeatureSet enabledFeatures, Entries entries) {
* entries.add(TEST_ITEM);
* }
* };
* }</pre>
*/
public abstract class FabricItemGroup extends ItemGroup implements IdentifiableItemGroup {
private final Identifier identifier;
public FabricItemGroup(Identifier identifier) {
super(-1, getText(Objects.requireNonNull(identifier, "identifier")));
this.identifier = identifier;
ItemGroupHelper.appendItemGroup(this);
}
private static Text getText(Identifier identifier) {
return Text.translatable("itemGroup.%s.%s".formatted(identifier.getNamespace(), identifier.getPath()));
}
@Override
public final Identifier getId() {
return identifier;
}
}

View file

@ -0,0 +1,464 @@
/*
* 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.itemgroup.v1;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.item.Item;
import net.minecraft.item.ItemConvertible;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.resource.featuretoggle.FeatureSet;
/**
* This class allows the entries of {@linkplain ItemGroup item groups} to be modified by the events in {@link ItemGroupEvents}.
*/
@ApiStatus.Experimental
public class FabricItemGroupEntries implements ItemGroup.Entries {
private final FeatureSet enabledFeatures;
private final List<ItemStack> displayStacks;
private final List<ItemStack> searchTabStacks;
@ApiStatus.Internal
public FabricItemGroupEntries(FeatureSet enabledFeatures, List<ItemStack> displayStacks, List<ItemStack> searchTabStacks) {
this.enabledFeatures = enabledFeatures;
this.displayStacks = displayStacks;
this.searchTabStacks = searchTabStacks;
}
/**
* @return The currently enabled feature set.
*/
public FeatureSet getEnabledFeatures() {
return enabledFeatures;
}
/**
* @return The stacks that will be shown in the tab in the creative mode inventory. This list can be modified.
*/
public List<ItemStack> getDisplayStacks() {
return displayStacks;
}
/**
* @return The stacks that will be searched by the creative mode inventory search. This list can be
* modified.
*/
public List<ItemStack> getSearchTabStacks() {
return searchTabStacks;
}
/**
* Adds a stack to the end of the item group. Duplicate stacks will be removed.
*
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
@Override
public void add(ItemStack stack, ItemGroup.StackVisibility visibility) {
if (isEnabled(stack)) {
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
this.displayStacks.add(stack);
this.searchTabStacks.add(stack);
}
case PARENT_TAB_ONLY -> this.displayStacks.add(stack);
case SEARCH_TAB_ONLY -> this.searchTabStacks.add(stack);
}
}
}
/**
* See {@link #prepend(ItemStack, ItemGroup.StackVisibility)}. Will use {@link ItemGroup.StackVisibility#PARENT_AND_SEARCH_TABS}
* for visibility.
*/
public void prepend(ItemStack stack) {
prepend(stack, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* Adds a stack to the beginning of the item group. Duplicate stacks will be removed.
*
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void prepend(ItemStack stack, ItemGroup.StackVisibility visibility) {
if (isEnabled(stack)) {
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
this.displayStacks.add(0, stack);
this.searchTabStacks.add(0, stack);
}
case PARENT_TAB_ONLY -> this.displayStacks.add(0, stack);
case SEARCH_TAB_ONLY -> this.searchTabStacks.add(0, stack);
}
}
}
/**
* See {@link #prepend(ItemStack)}. Automatically creates an {@link ItemStack} from the given item.
*/
public void prepend(ItemConvertible item) {
prepend(item, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* See {@link #prepend(ItemStack, net.minecraft.item.ItemGroup.StackVisibility)}.
* Automatically creates an {@link ItemStack} from the given item.
*/
public void prepend(ItemConvertible item, ItemGroup.StackVisibility visibility) {
prepend(new ItemStack(item), visibility);
}
/**
* See {@link #addAfter(ItemConvertible, Collection)}.
*/
public void addAfter(ItemConvertible afterLast, ItemStack... newStack) {
addAfter(afterLast, Arrays.asList(newStack));
}
/**
* See {@link #addAfter(ItemStack, Collection)}.
*/
public void addAfter(ItemStack afterLast, ItemStack... newStack) {
addAfter(afterLast, Arrays.asList(newStack));
}
/**
* See {@link #addAfter(ItemConvertible, Collection)}.
*/
public void addAfter(ItemConvertible afterLast, ItemConvertible... newItem) {
addAfter(afterLast, Arrays.stream(newItem).map(ItemStack::new).toList());
}
/**
* See {@link #addAfter(ItemStack, Collection)}.
*/
public void addAfter(ItemStack afterLast, ItemConvertible... newItem) {
addAfter(afterLast, Arrays.stream(newItem).map(ItemStack::new).toList());
}
/**
* See {@link #addAfter(ItemConvertible, Collection, net.minecraft.item.ItemGroup.StackVisibility)}.
*/
public void addAfter(ItemConvertible afterLast, Collection<ItemStack> newStacks) {
addAfter(afterLast, newStacks, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* See {@link #addAfter(ItemStack, Collection, net.minecraft.item.ItemGroup.StackVisibility)}.
*/
public void addAfter(ItemStack afterLast, Collection<ItemStack> newStacks) {
addAfter(afterLast, newStacks, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* Adds stacks after an existing item in the group, or at the end, if the item isn't in the group.
*
* @param afterLast Add {@code newStacks} after the last entry of this item in the group.
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addAfter(ItemConvertible afterLast, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addAfter(afterLast, newStacks, displayStacks);
addAfter(afterLast, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addAfter(afterLast, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addAfter(afterLast, newStacks, searchTabStacks);
}
}
/**
* Adds stacks after an existing stack in the group, or at the end, if the stack isn't in the group.
*
* @param afterLast Add {@code newStacks} after the last group entry matching this stack (compared using {@link ItemStack#canCombine}).
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addAfter(ItemStack afterLast, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addAfter(afterLast, newStacks, displayStacks);
addAfter(afterLast, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addAfter(afterLast, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addAfter(afterLast, newStacks, searchTabStacks);
}
}
/**
* Adds stacks after the last group entry matching a predicate, or at the end, if no entries match.
*
* @param afterLast Add {@code newStacks} after the last group entry matching this predicate.
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addAfter(Predicate<ItemStack> afterLast, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addAfter(afterLast, newStacks, displayStacks);
addAfter(afterLast, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addAfter(afterLast, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addAfter(afterLast, newStacks, searchTabStacks);
}
}
/**
* See {@link #addBefore(ItemConvertible, Collection)}.
*/
public void addBefore(ItemConvertible beforeFirst, ItemStack... newStack) {
addBefore(beforeFirst, Arrays.asList(newStack));
}
/**
* See {@link #addBefore(ItemStack, Collection)}.
*/
public void addBefore(ItemStack beforeFirst, ItemStack... newStack) {
addBefore(beforeFirst, Arrays.asList(newStack));
}
/**
* See {@link #addBefore(ItemConvertible, Collection)}.
*/
public void addBefore(ItemConvertible beforeFirst, ItemConvertible... newItem) {
addBefore(beforeFirst, Arrays.stream(newItem).map(ItemStack::new).toList());
}
/**
* See {@link #addBefore(ItemStack, Collection)}.
*/
public void addBefore(ItemStack beforeFirst, ItemConvertible... newItem) {
addBefore(beforeFirst, Arrays.stream(newItem).map(ItemStack::new).toList());
}
/**
* See {@link #addBefore(ItemConvertible, Collection, net.minecraft.item.ItemGroup.StackVisibility)}.
*/
public void addBefore(ItemConvertible beforeFirst, Collection<ItemStack> newStacks) {
addBefore(beforeFirst, newStacks, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* See {@link #addBefore(ItemStack, Collection, net.minecraft.item.ItemGroup.StackVisibility)}.
*/
public void addBefore(ItemStack beforeFirst, Collection<ItemStack> newStacks) {
addBefore(beforeFirst, newStacks, ItemGroup.StackVisibility.PARENT_AND_SEARCH_TABS);
}
/**
* Adds stacks before an existing item in the group, or at the end, if the item isn't in the group.
*
* @param beforeFirst Add {@code newStacks} before the first entry of this item in the group.
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addBefore(ItemConvertible beforeFirst, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addBefore(beforeFirst, newStacks, displayStacks);
addBefore(beforeFirst, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addBefore(beforeFirst, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addBefore(beforeFirst, newStacks, searchTabStacks);
}
}
/**
* Adds stacks before an existing stack to the group, or at the end, if the stack isn't in the group.
*
* @param beforeFirst Add {@code newStacks} before the first group entry matching this stack (compared using {@link ItemStack#canCombine}).
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addBefore(ItemStack beforeFirst, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addBefore(beforeFirst, newStacks, displayStacks);
addBefore(beforeFirst, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addBefore(beforeFirst, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addBefore(beforeFirst, newStacks, searchTabStacks);
}
}
/**
* Adds stacks before the first group entry matching a predicate, or at the end, if no entries match.
*
* @param beforeFirst Add {@code newStacks} before the first group entry matching this predicate.
* @param newStacks The stacks to add. Only {@linkplain #isEnabled(ItemStack) enabled} stacks will be added.
* @param visibility Determines whether the stack will be shown in the tab itself, returned
* for searches, or both.
*/
public void addBefore(Predicate<ItemStack> beforeFirst, Collection<ItemStack> newStacks, ItemGroup.StackVisibility visibility) {
newStacks = getEnabledStacks(newStacks);
if (newStacks.isEmpty()) {
return;
}
switch (visibility) {
case PARENT_AND_SEARCH_TABS -> {
addBefore(beforeFirst, newStacks, displayStacks);
addBefore(beforeFirst, newStacks, searchTabStacks);
}
case PARENT_TAB_ONLY -> addBefore(beforeFirst, newStacks, displayStacks);
case SEARCH_TAB_ONLY -> addBefore(beforeFirst, newStacks, searchTabStacks);
}
}
/**
* @return True if the item of a given stack is enabled in the current {@link FeatureSet}.
* @see Item#method_45382
*/
private boolean isEnabled(ItemStack stack) {
return stack.getItem().method_45382(enabledFeatures);
}
private Collection<ItemStack> getEnabledStacks(Collection<ItemStack> newStacks) {
// If not all stacks are enabled, filter the list, otherwise use it as-is
if (newStacks.stream().allMatch(this::isEnabled)) {
return newStacks;
}
return newStacks.stream().filter(this::isEnabled).toList();
}
/**
* Adds the {@link ItemStack} before the first match, if no matches the {@link ItemStack} is appended to the end of the {@link ItemGroup}.
*/
private static void addBefore(Predicate<ItemStack> predicate, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
for (int i = 0; i < addTo.size(); i++) {
if (predicate.test(addTo.get(i))) {
addTo.subList(i, i).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
private static void addAfter(Predicate<ItemStack> predicate, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
// Iterate in reverse to add after the last match
for (int i = addTo.size() - 1; i >= 0; i--) {
if (predicate.test(addTo.get(i))) {
addTo.subList(i + 1, i + 1).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
private static void addBefore(ItemStack anchor, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
for (int i = 0; i < addTo.size(); i++) {
if (ItemStack.canCombine(anchor, addTo.get(i))) {
addTo.subList(i, i).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
private static void addAfter(ItemStack anchor, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
// Iterate in reverse to add after the last match
for (int i = addTo.size() - 1; i >= 0; i--) {
if (ItemStack.canCombine(anchor, addTo.get(i))) {
addTo.subList(i + 1, i + 1).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
private static void addBefore(ItemConvertible anchor, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
Item anchorItem = anchor.asItem();
for (int i = 0; i < addTo.size(); i++) {
if (addTo.get(i).isOf(anchorItem)) {
addTo.subList(i, i).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
private static void addAfter(ItemConvertible anchor, Collection<ItemStack> newStacks, List<ItemStack> addTo) {
Item anchorItem = anchor.asItem();
// Iterate in reverse to add after the last match
for (int i = addTo.size() - 1; i >= 0; i--) {
if (addTo.get(i).isOf(anchorItem)) {
addTo.subList(i + 1, i + 1).addAll(newStacks);
return;
}
}
// Anchor not found, add to end
addTo.addAll(newStacks);
}
}

View file

@ -14,10 +14,19 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.impl.resource.loader; package net.fabricmc.fabric.api.itemgroup.v1;
import net.minecraft.resource.ResourcePackSource; import net.minecraft.item.ItemGroup;
import net.minecraft.util.Identifier;
public interface FabricNamespaceResourceManagerEntry { /**
void setFabricPackSource(ResourcePackSource packSource); * This interface is automatically injected to {@link ItemGroup}.
*/
public interface IdentifiableItemGroup {
/**
* {@return the unique identifier of this {@link ItemGroup}}.
*/
default Identifier getId() {
throw new AssertionError("Not implemented");
}
} }

View file

@ -0,0 +1,67 @@
/*
* 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.itemgroup.v1;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.fabricmc.fabric.impl.itemgroup.ItemGroupEventsImpl;
/**
* Holds events related to {@link ItemGroups}.
*
* @see FabricItemGroup
*/
public final class ItemGroupEvents {
private ItemGroupEvents() {
}
/**
* This event allows the entries of any item group to be modified.
* <p/>
* If you know beforehand which item group you'd like to modify, use {@link #modifyEntriesEvent(ItemGroup)}
* or {@link #modifyEntriesEvent(Identifier)} instead.
* <p/>
* This event is invoked after those two more specific events.
*/
public static final Event<ModifyEntriesAll> MODIFY_ENTRIES_ALL = EventFactory.createArrayBacked(ModifyEntriesAll.class, callbacks -> (group, entries) -> {
for (ModifyEntriesAll callback : callbacks) {
callback.modifyEntries(group, entries);
}
});
public static Event<ModifyEntries> modifyEntriesEvent(ItemGroup itemGroup) {
return modifyEntriesEvent(itemGroup.getId());
}
public static Event<ModifyEntries> modifyEntriesEvent(Identifier groupId) {
return ItemGroupEventsImpl.getOrCreateModifyEntriesEvent(groupId);
}
@FunctionalInterface
public interface ModifyEntries {
void modifyEntries(FabricItemGroupEntries entries);
}
@FunctionalInterface
public interface ModifyEntriesAll {
void modifyEntries(ItemGroup group, FabricItemGroupEntries entries);
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.itemgroup;
import java.util.HashMap;
import java.util.Map;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
@ApiStatus.Internal
public class ItemGroupEventsImpl {
private static final Map<Identifier, Event<ItemGroupEvents.ModifyEntries>> IDENTIFIER_EVENT_MAP = new HashMap<>();
public static Event<ItemGroupEvents.ModifyEntries> getOrCreateModifyEntriesEvent(Identifier identifier) {
return IDENTIFIER_EVENT_MAP.computeIfAbsent(identifier, (g -> createModifyEvent()));
}
@Nullable
public static Event<ItemGroupEvents.ModifyEntries> getModifyEntriesEvent(Identifier identifier) {
return IDENTIFIER_EVENT_MAP.get(identifier);
}
private static Event<ItemGroupEvents.ModifyEntries> createModifyEvent() {
return EventFactory.createArrayBacked(ItemGroupEvents.ModifyEntries.class, callbacks -> (entries) -> {
for (ItemGroupEvents.ModifyEntries callback : callbacks) {
callback.modifyEntries(entries);
}
});
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.itemgroup;
import org.apache.commons.lang3.ArrayUtils;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.mixin.itemgroup.ItemGroupAccessor;
import net.fabricmc.fabric.mixin.itemgroup.ItemGroupsAccessor;
@ApiStatus.Internal
public final class ItemGroupHelper {
private ItemGroupHelper() {
}
public static void appendItemGroup(FabricItemGroup itemGroup) {
for (ItemGroup existingGroup : ItemGroups.GROUPS) {
if (existingGroup.getId().equals(itemGroup.getId())) {
throw new IllegalStateException("Duplicate item group: " + itemGroup.getId());
}
}
final int index = ItemGroups.GROUPS.length;
final ItemGroup[] itemGroups = ArrayUtils.add(ItemGroups.GROUPS, itemGroup);
((ItemGroupAccessor) itemGroup).setIndex(index);
ItemGroupsAccessor.setGroups(ItemGroupsAccessor.invokeAsArray(itemGroups));
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.itemgroup;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.ApiStatus;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.util.Identifier;
@ApiStatus.Internal
public final class MinecraftItemGroups {
public static final Identifier BUILDING_BLOCKS_ID = new Identifier("minecraft:building_blocks");
public static final Identifier NATURE_ID = new Identifier("minecraft:nature");
public static final Identifier FUNCTIONAL_ID = new Identifier("minecraft:functional");
public static final Identifier REDSTONE_ID = new Identifier("minecraft:redstone");
public static final Identifier HOTBAR_ID = new Identifier("minecraft:hotbar");
public static final Identifier SEARCH_ID = new Identifier("minecraft:search");
public static final Identifier TOOLS_ID = new Identifier("minecraft:tools");
public static final Identifier COMBAT_ID = new Identifier("minecraft:combat");
public static final Identifier CONSUMABLES_ID = new Identifier("minecraft:consumables");
public static final Identifier CRAFTING_ID = new Identifier("minecraft:crafting");
public static final Identifier SPAWN_EGGS_ID = new Identifier("minecraft:spawn_eggs");
public static final Identifier INVENTORY_ID = new Identifier("minecraft:inventory");
public static final Map<ItemGroup, Identifier> GROUP_ID_MAP = new ImmutableMap.Builder<ItemGroup, Identifier>()
.put(ItemGroups.BUILDING_BLOCKS, MinecraftItemGroups.BUILDING_BLOCKS_ID)
.put(ItemGroups.NATURE, MinecraftItemGroups.NATURE_ID)
.put(ItemGroups.FUNCTIONAL, MinecraftItemGroups.FUNCTIONAL_ID)
.put(ItemGroups.REDSTONE, MinecraftItemGroups.REDSTONE_ID)
.put(ItemGroups.HOTBAR, MinecraftItemGroups.HOTBAR_ID)
.put(ItemGroups.SEARCH, MinecraftItemGroups.SEARCH_ID)
.put(ItemGroups.TOOLS, MinecraftItemGroups.TOOLS_ID)
.put(ItemGroups.COMBAT, MinecraftItemGroups.COMBAT_ID)
.put(ItemGroups.CONSUMABLES, MinecraftItemGroups.CONSUMABLES_ID)
.put(ItemGroups.CRAFTING, MinecraftItemGroups.CRAFTING_ID)
.put(ItemGroups.SPAWN_EGGS, MinecraftItemGroups.SPAWN_EGGS_ID)
.put(ItemGroups.INVENTORY, MinecraftItemGroups.INVENTORY_ID)
.build();
private MinecraftItemGroups() {
}
}

View file

@ -14,16 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.mixin.resource.loader; package net.fabricmc.fabric.mixin.itemgroup;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Accessor;
import net.minecraft.resource.FileResourcePackProvider; import net.minecraft.item.ItemGroup;
import net.minecraft.resource.ResourcePackSource;
@Mixin(FileResourcePackProvider.class) @Mixin(ItemGroup.class)
public interface FileResourcePackProviderAccessor { public interface ItemGroupAccessor {
@Accessor("source") @Accessor
ResourcePackSource getResourcePackSource(); @Mutable
void setIndex(int index);
} }

View file

@ -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.mixin.itemgroup;
import java.util.LinkedList;
import java.util.Objects;
import org.objectweb.asm.Opcodes;
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.CallbackInfoReturnable;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStackSet;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.itemgroup.v1.IdentifiableItemGroup;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroupEntries;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.impl.itemgroup.ItemGroupEventsImpl;
import net.fabricmc.fabric.impl.itemgroup.MinecraftItemGroups;
@Mixin(ItemGroup.class)
abstract class ItemGroupMixin implements IdentifiableItemGroup {
@Shadow
@Final
private int index;
@Shadow
private ItemStackSet displayStacks;
@Shadow
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) {
// Sanity check for the injection point. It should be after these fields are set.
Objects.requireNonNull(displayStacks, "displayStacks");
Objects.requireNonNull(searchTabStacks, "searchTabStacks");
// Convert the entries to lists
var mutableDisplayStacks = new LinkedList<>(displayStacks);
var mutableSearchTabStacks = new LinkedList<>(searchTabStacks);
var entries = new FabricItemGroupEntries(enabledFeatures, mutableDisplayStacks, mutableSearchTabStacks);
final Event<ItemGroupEvents.ModifyEntries> modifyEntriesEvent = ItemGroupEventsImpl.getModifyEntriesEvent(getId());
if (modifyEntriesEvent != null) {
modifyEntriesEvent.invoker().modifyEntries(entries);
}
// Now trigger the global event
ItemGroup self = (ItemGroup) (Object) this;
ItemGroupEvents.MODIFY_ENTRIES_ALL.invoker().modifyEntries(self, entries);
// Convert the stacks back to sets after the events had a chance to modify them
displayStacks.clear();
displayStacks.addAll(mutableDisplayStacks);
searchTabStacks.clear();
searchTabStacks.addAll(mutableSearchTabStacks);
}
@Override
public Identifier getId() {
final Identifier identifier = MinecraftItemGroups.GROUP_ID_MAP.get((ItemGroup) (Object) this);
if (identifier == null) {
// Fallback when no ID is found for this ItemGroup.
return new Identifier("minecraft", "unidentified_" + index);
}
return identifier;
}
}

View file

@ -14,29 +14,28 @@
* limitations under the License. * limitations under the License.
*/ */
package net.fabricmc.fabric.mixin.item.group; package net.fabricmc.fabric.mixin.itemgroup;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.fabricmc.fabric.impl.item.group.ItemGroupExtensions; @Mixin(ItemGroups.class)
public interface ItemGroupsAccessor {
@Mixin(ItemGroup.class) @Accessor("GROUPS")
public abstract class ItemGroupMixin implements ItemGroupExtensions {
@Shadow
@Final @Final
@Mutable @Mutable
public static ItemGroup[] GROUPS; static void setGroups(ItemGroup[] groups) {
throw new AssertionError();
}
@Override @Invoker
public void fabric_expandArray() { static ItemGroup[] invokeAsArray(ItemGroup[] groups) {
ItemGroup[] tempGroups = GROUPS; throw new AssertionError();
GROUPS = new ItemGroup[GROUPS.length + 1];
System.arraycopy(tempGroups, 0, GROUPS, 0, tempGroups.length);
} }
} }

View file

@ -0,0 +1,38 @@
/*
* 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.itemgroup;
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.item.ItemGroup;
import net.minecraft.item.ItemGroups;
@Mixin(ItemGroups.class)
abstract class ItemGroupsMixin {
@Inject(method = "asArray", at = @At("HEAD"))
private static void asArray(ItemGroup[] groups, CallbackInfoReturnable<ItemGroup[]> cir) {
// Ensure that all item groups have a nonnull id.
for (ItemGroup group : groups) {
if (group.getId() == null) {
throw new NullPointerException("Item group %s has a null id".formatted(group.getClass().getName()));
}
}
}
}

View file

@ -0,0 +1,6 @@
accessWidener v2 named
transitive-accessible class net/minecraft/item/ItemGroup$StackVisibility
accessible class net/minecraft/item/ItemGroup$Entries
accessible class net/minecraft/item/ItemGroup$EntriesImpl

View file

@ -0,0 +1,14 @@
{
"required": true,
"package": "net.fabricmc.fabric.mixin.itemgroup",
"compatibilityLevel": "JAVA_17",
"mixins": [
"ItemGroupsAccessor",
"ItemGroupMixin",
"ItemGroupAccessor",
"ItemGroupsMixin"
],
"injectors": {
"defaultRequire": 1
}
}

View file

@ -1,11 +1,11 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "fabric-item-groups-v0", "id": "fabric-item-group-api-v1",
"name": "Fabric Item Groups (v0)", "name": "Fabric Item Group API (v1)",
"version": "${version}", "version": "${version}",
"environment": "*", "environment": "*",
"license": "Apache-2.0", "license": "Apache-2.0",
"icon": "assets/fabric-item-groups-v0/icon.png", "icon": "assets/fabric-item-group-api-v1/icon.png",
"contact": { "contact": {
"homepage": "https://fabricmc.net", "homepage": "https://fabricmc.net",
"irc": "irc://irc.esper.net:6667/fabric", "irc": "irc://irc.esper.net:6667/fabric",
@ -16,20 +16,23 @@
"FabricMC" "FabricMC"
], ],
"depends": { "depends": {
"fabricloader": ">=0.6.0", "fabricloader": ">=0.14.9",
"minecraft": ">=1.15-",
"fabric-api-base": "*", "fabric-api-base": "*",
"fabric-resource-loader-v0": "*" "fabric-resource-loader-v0": "*"
}, },
"description": "An API for adding custom item groups.", "description": "An API for adding custom item groups.",
"mixins": [ "mixins": [
"fabric-item-groups-v0.mixins.json", "fabric-item-group-api-v1.mixins.json",
{ {
"config": "fabric-item-groups-v0.client.mixins.json", "config": "fabric-item-group-api-v1.client.mixins.json",
"environment": "client" "environment": "client"
} }
], ],
"accessWidener": "fabric-item-group-api-v1.accesswidener",
"custom": { "custom": {
"fabric-api:module-lifecycle": "stable" "fabric-api:module-lifecycle": "stable",
"loom:injected_interfaces": {
"net/minecraft/class_1761": ["net/fabricmc/fabric/api/itemgroup/v1/IdentifiableItemGroup"]
}
} }
} }

View file

@ -0,0 +1,94 @@
/*
* 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.item.group;
import com.google.common.base.Preconditions;
import net.minecraft.block.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemGroups;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.impl.itemgroup.MinecraftItemGroups;
public class ItemGroupTest implements ModInitializer {
private static final String MOD_ID = "fabric-item-group-api-v1-testmod";
private static Item TEST_ITEM;
//Adds an item group with all items in it
private static final ItemGroup ITEM_GROUP = new FabricItemGroup(new Identifier(MOD_ID, "test_group")) {
@Override
public ItemStack createIcon() {
return new ItemStack(Items.DIAMOND);
}
@Override
protected void addItems(FeatureSet featureSet, Entries entries) {
entries.addAll(Registry.ITEM.stream()
.map(ItemStack::new)
.toList());
}
};
@Override
public void onInitialize() {
TEST_ITEM = Registry.register(Registry.ITEM, new Identifier("fabric-item-groups-v0-testmod", "item_test_group"), new Item(new Item.Settings()));
checkAllVanillaGroupsHaveAssignedIds();
ItemGroupEvents.modifyEntriesEvent(ItemGroups.BUILDING_BLOCKS).register((content) -> {
content.add(TEST_ITEM);
content.addBefore(Blocks.OAK_FENCE, Items.DIAMOND, Items.DIAMOND_BLOCK);
content.addAfter(Blocks.OAK_DOOR, Items.EMERALD, Items.EMERALD_BLOCK);
// Test adding when the existing entry does not exist.
content.addBefore(Blocks.BEDROCK, Items.GOLD_INGOT, Items.GOLD_BLOCK);
content.addAfter(Blocks.BEDROCK, Items.IRON_INGOT, Items.IRON_BLOCK);
});
// Add a differently damaged pickaxe to all groups
ItemGroupEvents.MODIFY_ENTRIES_ALL.register((group, content) -> {
ItemStack minDmgPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
minDmgPickaxe.setDamage(1);
content.prepend(minDmgPickaxe);
ItemStack maxDmgPickaxe = new ItemStack(Items.DIAMOND_PICKAXE);
maxDmgPickaxe.setDamage(maxDmgPickaxe.getMaxDamage() - 1);
content.add(maxDmgPickaxe);
});
}
private static void checkAllVanillaGroupsHaveAssignedIds() {
for (ItemGroup group : ItemGroups.GROUPS) {
if (group instanceof FabricItemGroup) {
continue; // Skip groups added by test mods
}
Preconditions.checkArgument(MinecraftItemGroups.GROUP_ID_MAP.containsKey(group),
"Missing ID for Vanilla ItemGroup %s. Assign one in MinecraftItemGroups.", group);
}
}
}

View file

@ -1,12 +1,12 @@
{ {
"schemaVersion": 1, "schemaVersion": 1,
"id": "fabric-item-groups-v0-testmod", "id": "fabric-item-group-api-v1-testmod",
"name": "Fabric Item Groups (v0) Test Mod", "name": "Fabric Item Group API (v1) Test Mod",
"version": "1.0.0", "version": "1.0.0",
"environment": "*", "environment": "*",
"license": "Apache-2.0", "license": "Apache-2.0",
"depends": { "depends": {
"fabric-item-groups-v0": "*" "fabric-item-group-api-v1": "*"
}, },
"entrypoints": { "entrypoints": {
"main": [ "main": [

View file

@ -1,7 +0,0 @@
archivesBaseName = "fabric-item-groups-v0"
version = getSubprojectVersion(project)
moduleDependencies(project, [
'fabric-api-base',
'fabric-resource-loader-v0'
])

View file

@ -1,185 +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.client.itemgroup;
import java.util.List;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Supplier;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.collection.DefaultedList;
import net.fabricmc.fabric.impl.item.group.ItemGroupExtensions;
/**
* A builder for {@link ItemGroup}. Item groups are used to group items in the creative
* inventory.
*
* <p>Example of creating an empty group (recommended for modded item-only group):</p>
* <pre>{@code
* MY_GROUP = FabricItemGroupBuilder.build(
* new Identifier("my_mod", "example_group"),
* () -> new ItemStack(MY_ITEM);
* );
* // Use item settings to assign a group. Otherwise, it won't appear on creative inventory
* // search result.
* MY_ITEM = new Item(new Item.Settings().group(MY_GROUP));
* }</pre>
*
* <p>Example of creating a group with vanilla item stacks:</p>
* <pre>{@code
* ItemGroup myGroup = FabricItemGroupBuilder.create(new Identifier("my_mod", "group_2"))
* .icon(Items.STONE::getDefaultStack)
* .appendItems((stacks) -> {
* stacks.add(new ItemStack(Items.STONE));
* stacks.add(new ItemStack(Items.COBBLESTONE));
* })
* .build();
* }</pre>
*
* <h2 id="search">Creative inventory searching</h2>
* <p>Creative inventory search is implemented as a special item group. Adding items with
* the builder by default does not add them to the search result; to make the item searchable,
* set the item group via {@link Item.Settings#group(ItemGroup)} as well. If there are
* multiple searchable item stacks of the item (such as colored variants or ones with
* different NBT), override {@link Item#appendStacks(ItemGroup, DefaultedList)} on your
* item as well. This should be called by {@link #appendItems(BiConsumer)} to actually add
* items to your item group.</p>
*/
public final class FabricItemGroupBuilder {
private final Identifier identifier;
private Supplier<ItemStack> stackSupplier = () -> ItemStack.EMPTY;
private BiConsumer<List<ItemStack>, ItemGroup> stacksForDisplay;
private FabricItemGroupBuilder(Identifier identifier) {
Objects.requireNonNull(identifier, "identifier cannot be null");
this.identifier = identifier;
}
/**
* Creates a new item group builder.
*
* @param identifier the id of the ItemGroup, to be used as the translation key
* @return a new builder
*/
public static FabricItemGroupBuilder create(Identifier identifier) {
return new FabricItemGroupBuilder(identifier);
}
/**
* Sets an icon for the group. This is displayed on the creative inventory tab.
*
* @param stackSupplier the supplier that returns the item stack to be used as an icon
* @return this builder
*/
public FabricItemGroupBuilder icon(Supplier<ItemStack> stackSupplier) {
Objects.requireNonNull(stackSupplier, "icon cannot be null");
this.stackSupplier = stackSupplier;
return this;
}
/**
* This allows for a custom list of items to be displayed in a tab, this enabled tabs to be created with a custom set of items.
*
* @param appender Add ItemStack's to this list to show in the ItemGroup
* @return a reference to the FabricItemGroupBuilder
* @deprecated use {@link FabricItemGroupBuilder#appendItems(Consumer)}
*/
@Deprecated
public FabricItemGroupBuilder stacksForDisplay(Consumer<List<ItemStack>> appender) {
return appendItems(appender);
}
/**
* Sets the item stacks of this item group, by having the consumer add them to the passed list.
* This bypasses {@link Item#appendStacks}, and by default, does not append the stack to the search result.
* To add modded items, consider setting the group via {@linkplain Item.Settings#group(ItemGroup)
* item groups} in addition to this, as that adds the item stack to the search result.
* See the <a href="#search">creative inventory searching</a> section for details.
*
* <p>Calling this multiple times overwrites the previously set stacks.</p>
*
* @param stacksForDisplay a callback that adds item stacks to the passed list
* @return this builder
*/
public FabricItemGroupBuilder appendItems(Consumer<List<ItemStack>> stacksForDisplay) {
return appendItems((itemStacks, itemGroup) -> stacksForDisplay.accept(itemStacks));
}
/**
* Sets the item stacks of this item group, by having the consumer add them to the passed list.
* This bypasses {@link Item#appendStacks}, and by default, does not append the stack to the search result.
* To add modded items, consider setting the group via {@linkplain Item.Settings#group(ItemGroup)
* item groups} in addition to this, as that adds the item stack to the search result.
* See the <a href="#search">creative inventory searching</a> section for details.
*
* <p>Compared to the other overload, this one also passes the new ItemGroup.
* This allows you to call {@link Item#appendStacks} yourself if you want.</p>
*
* <p>Calling this multiple times overwrites the previously set stacks.</p>
*
* @param stacksForDisplay a callback that adds item stacks to the passed list
* @return this builder
*/
public FabricItemGroupBuilder appendItems(BiConsumer<List<ItemStack>, ItemGroup> stacksForDisplay) {
this.stacksForDisplay = stacksForDisplay;
return this;
}
/**
* This is a single method that makes creating an empty ItemGroup with an icon one call.
* Items should be added using {@linkplain Item.Settings#group(ItemGroup) item settings}.
* Useful for modded item-only group.
*
* @param identifier the id of the ItemGroup, to be used as the translation key
* @param stackSupplier the supplier that returns the item stack to be used as an icon
* @return an instance of the built ItemGroup
*/
public static ItemGroup build(Identifier identifier, Supplier<ItemStack> stackSupplier) {
return new FabricItemGroupBuilder(identifier).icon(stackSupplier).build();
}
/**
* Creates an instance of the ItemGroup.
*
* @return an instance of the built ItemGroup
*/
public ItemGroup build() {
((ItemGroupExtensions) ItemGroup.BUILDING_BLOCKS).fabric_expandArray();
return new ItemGroup(ItemGroup.GROUPS.length - 1, String.format("%s.%s", identifier.getNamespace(), identifier.getPath())) {
@Override
public ItemStack createIcon() {
return stackSupplier.get();
}
@Override
public void appendStacks(DefaultedList<ItemStack> stacks) {
if (stacksForDisplay != null) {
stacksForDisplay.accept(stacks, this);
return;
}
super.appendStacks(stacks);
}
};
}
}

Some files were not shown because too many files have changed in this diff Show more