Add data generation for custom items and blocks, refactor and modularize item and block registration.

This commit is contained in:
2025-06-15 22:12:32 -07:00
parent f0f9239a74
commit e6d2a9d6a0
5 changed files with 179 additions and 25 deletions

View File

@@ -1,14 +1,23 @@
package com.smrising.firstmod.client;
import com.smrising.firstmod.Firstmod;
import com.smrising.firstmod.ModBlocks;
import com.smrising.firstmod.ModItems;
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricBlockLootTableProvider;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricLanguageProvider;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricTagProvider;
import net.minecraft.client.data.BlockStateModelGenerator;
import net.minecraft.client.data.ItemModelGenerator;
import net.minecraft.client.data.Models;
import net.minecraft.data.recipe.RecipeExporter;
import net.minecraft.data.recipe.RecipeGenerator;
import net.minecraft.item.Items;
import net.minecraft.recipe.book.RecipeCategory;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.tag.BlockTags;
@@ -22,28 +31,44 @@ public class FirstmodDataGenerator implements DataGeneratorEntrypoint {
pack.addProvider(ModBlockTagProvider::new);
pack.addProvider(ModLootTableProvider::new);
pack.addProvider(ModModelProvider::new);
pack.addProvider(ModLanguageProvider::new);
pack.addProvider(ModRecipeProvider::new);
}
private static class ModBlockTagProvider extends FabricTagProvider.BlockTagProvider {
public ModBlockTagProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
public ModBlockTagProvider(
FabricDataOutput output,
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected void configure(RegistryWrapper.WrapperLookup arg) {
getOrCreateTagBuilder(BlockTags.PICKAXE_MINEABLE)
.add(Firstmod.EXAMPLE_BLOCK);
.add(ModBlocks.EXAMPLE_BLOCK);
}
@Override
public String getName() {
return String.format("%sBlockTagProvider", Firstmod.MOD_ID);
}
}
private static class ModLootTableProvider extends FabricBlockLootTableProvider {
public ModLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
public ModLootTableProvider(
FabricDataOutput dataOutput,
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(dataOutput, registriesFuture);
}
@Override
public void generate() {
addDrop(Firstmod.EXAMPLE_BLOCK);
addDrop(ModBlocks.EXAMPLE_BLOCK);
}
@Override
public String getName() {
return String.format("%sLootTableProvider", Firstmod.MOD_ID);
}
}
@@ -54,13 +79,63 @@ public class FirstmodDataGenerator implements DataGeneratorEntrypoint {
@Override
public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) {
blockStateModelGenerator.registerSimpleCubeAll(Firstmod.EXAMPLE_BLOCK);
blockStateModelGenerator.registerSimpleCubeAll(ModBlocks.EXAMPLE_BLOCK);
}
@Override
public void generateItemModels(ItemModelGenerator itemModelGenerator) {
// Item model is automatically generated from block model
itemModelGenerator.register(ModItems.SUSPICIOUS_SUBSTANCE, Models.GENERATED);
}
@Override
public String getName() {
return String.format("%sModelProvider", Firstmod.MOD_ID);
}
}
private static class ModLanguageProvider extends FabricLanguageProvider {
public ModLanguageProvider(
FabricDataOutput output,
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
}
@Override
public void generateTranslations(RegistryWrapper.WrapperLookup wrapperLookup, TranslationBuilder translationBuilder) {
translationBuilder.add(ModBlocks.EXAMPLE_BLOCK, "Example Block");
translationBuilder.add(ModItems.SUSPICIOUS_SUBSTANCE, "Suspicious Substance");
}
@Override
public String getName() {
return String.format("%sLanguageProvider", Firstmod.MOD_ID);
}
}
private static class ModRecipeProvider extends FabricRecipeProvider {
public ModRecipeProvider(
FabricDataOutput output,
CompletableFuture<RegistryWrapper.WrapperLookup> registriesFuture) {
super(output, registriesFuture);
}
@Override
protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registryLookup, RecipeExporter exporter) {
return new RecipeGenerator(registryLookup, exporter) {
@Override
public void generate() {
//RegistryWrapper.Impl<Item> itemLookup = registries.getOrThrow(RegistryKeys.ITEM);
createShapeless(RecipeCategory.REDSTONE, ModItems.SUSPICIOUS_SUBSTANCE)
.input(Items.REDSTONE, 9)
.criterion(hasItem(Items.REDSTONE), conditionsFromItem(Items.REDSTONE)).offerTo(exporter);
}
};
}
@Override
public String getName() {
return String.format("%sRecipeProvider", Firstmod.MOD_ID);
}
}
}

View File

@@ -1,30 +1,14 @@
package com.smrising.firstmod;
import net.fabricmc.api.ModInitializer;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.item.Items;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class Firstmod implements ModInitializer {
public static final Block EXAMPLE_BLOCK = register(Block::new, Block.Settings.create().strength(4.0f));
private static Block register(Function<AbstractBlock.Settings, Block> factory, AbstractBlock.Settings settings) {
final Identifier identifier = Identifier.of("tutorial", "example_block");
final RegistryKey<Block> registryKey = RegistryKey.of(RegistryKeys.BLOCK, identifier);
final Block block = Blocks.register(registryKey, factory, settings);
Items.register(block);
return block;
}
public static final String MOD_ID = "firstmod";
@Override
public void onInitialize() {
ModItems.init();
ModBlocks.init();
}
}

View File

@@ -0,0 +1,53 @@
package com.smrising.firstmod;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class ModBlocks {
public static final Block EXAMPLE_BLOCK = register(
"example_block",
Block::new,
AbstractBlock.Settings.create().strength(4.0f),
true
);
private static Block register(String name, Function<AbstractBlock.Settings, Block> blockFactory, AbstractBlock.Settings settings, boolean shouldRegisterItem) {
// Create a registry key for the block
RegistryKey<Block> blockKey = keyOfBlock(name);
// Create the block instance
Block block = blockFactory.apply(settings.registryKey(blockKey));
// Sometimes, you may not want to register an item for the block.
// Eg: if it's a technical block like `minecraft:moving_piston` or `minecraft:end_gateway`
if (shouldRegisterItem) {
// Items need to be registered with a different type of registry key, but the ID
// can be the same.
RegistryKey<Item> itemKey = keyOfItem(name);
BlockItem blockItem = new BlockItem(block, new Item.Settings().registryKey(itemKey));
Registry.register(Registries.ITEM, itemKey, blockItem);
}
return Registry.register(Registries.BLOCK, blockKey, block);
}
private static RegistryKey<Block> keyOfBlock(String name) {
return RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(Firstmod.MOD_ID, name));
}
private static RegistryKey<Item> keyOfItem(String name) {
return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(Firstmod.MOD_ID, name));
}
public static void init() {
}
}

View File

@@ -0,0 +1,42 @@
package com.smrising.firstmod;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.fabricmc.fabric.api.registry.CompostingChanceRegistry;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class ModItems {
public static final Item SUSPICIOUS_SUBSTANCE = register("suspicious_substance", Item::new, new Item.Settings());
// public static final RegistryKey<ItemGroup> CUSTOM_ITEM_GROUP_KEY = RegistryKey.of(Registries.ITEM_GROUP.getKey(), Identifier.of(FabricDocsReference.MOD_ID, "item_group"));
// public static final ItemGroup CUSTOM_ITEM_GROUP = FabricItemGroup.builder()
// .icon(() -> new ItemStack(ModItems.GUIDITE_SWORD))
// .displayName(Text.translatable("itemGroup.fabric_docs_reference"))
// .build();
public static Item register(String name, Function<Item.Settings, Item> itemFactory, Item.Settings settings) {
// Create the item key.
RegistryKey<Item> itemKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(Firstmod.MOD_ID, name));
// Create the item instance.
Item item = itemFactory.apply(settings.registryKey(itemKey));
// Register the item.
Registry.register(Registries.ITEM, itemKey, item);
return item;
}
public static void init() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS)
.register((itemGroup) -> itemGroup.add(ModItems.SUSPICIOUS_SUBSTANCE));
CompostingChanceRegistry.INSTANCE.add(ModItems.SUSPICIOUS_SUBSTANCE, 0.3f);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B