From e6d2a9d6a0b4e7f54721465b13fd5903881f4ce7 Mon Sep 17 00:00:00 2001 From: Spencer Jones Date: Sun, 15 Jun 2025 22:12:32 -0700 Subject: [PATCH] Add data generation for custom items and blocks, refactor and modularize item and block registration. --- .../client/FirstmodDataGenerator.java | 87 ++++++++++++++++-- .../java/com/smrising/firstmod/Firstmod.java | 22 +---- .../java/com/smrising/firstmod/ModBlocks.java | 53 +++++++++++ .../java/com/smrising/firstmod/ModItems.java | 42 +++++++++ .../textures/item/suspicious_substance.png | Bin 0 -> 329 bytes 5 files changed, 179 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/smrising/firstmod/ModBlocks.java create mode 100644 src/main/java/com/smrising/firstmod/ModItems.java create mode 100644 src/main/resources/assets/firstmod/textures/item/suspicious_substance.png diff --git a/src/client/java/com/smrising/firstmod/client/FirstmodDataGenerator.java b/src/client/java/com/smrising/firstmod/client/FirstmodDataGenerator.java index 4447fc3..ef1fe3f 100644 --- a/src/client/java/com/smrising/firstmod/client/FirstmodDataGenerator.java +++ b/src/client/java/com/smrising/firstmod/client/FirstmodDataGenerator.java @@ -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 registriesFuture) { + public ModBlockTagProvider( + FabricDataOutput output, + CompletableFuture 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 registriesFuture) { + public ModLootTableProvider( + FabricDataOutput dataOutput, + CompletableFuture 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 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 registriesFuture) { + super(output, registriesFuture); + } + + @Override + protected RecipeGenerator getRecipeGenerator(RegistryWrapper.WrapperLookup registryLookup, RecipeExporter exporter) { + return new RecipeGenerator(registryLookup, exporter) { + @Override + public void generate() { + //RegistryWrapper.Impl 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); + } + } } diff --git a/src/main/java/com/smrising/firstmod/Firstmod.java b/src/main/java/com/smrising/firstmod/Firstmod.java index 6b7a8d2..c3c3801 100644 --- a/src/main/java/com/smrising/firstmod/Firstmod.java +++ b/src/main/java/com/smrising/firstmod/Firstmod.java @@ -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 factory, AbstractBlock.Settings settings) { - final Identifier identifier = Identifier.of("tutorial", "example_block"); - final RegistryKey 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(); } } diff --git a/src/main/java/com/smrising/firstmod/ModBlocks.java b/src/main/java/com/smrising/firstmod/ModBlocks.java new file mode 100644 index 0000000..609fc56 --- /dev/null +++ b/src/main/java/com/smrising/firstmod/ModBlocks.java @@ -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 blockFactory, AbstractBlock.Settings settings, boolean shouldRegisterItem) { + // Create a registry key for the block + RegistryKey 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 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 keyOfBlock(String name) { + return RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(Firstmod.MOD_ID, name)); + } + + private static RegistryKey keyOfItem(String name) { + return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(Firstmod.MOD_ID, name)); + } + + public static void init() { + } +} diff --git a/src/main/java/com/smrising/firstmod/ModItems.java b/src/main/java/com/smrising/firstmod/ModItems.java new file mode 100644 index 0000000..a7de76d --- /dev/null +++ b/src/main/java/com/smrising/firstmod/ModItems.java @@ -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 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 itemFactory, Item.Settings settings) { + // Create the item key. + RegistryKey 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); + } +} diff --git a/src/main/resources/assets/firstmod/textures/item/suspicious_substance.png b/src/main/resources/assets/firstmod/textures/item/suspicious_substance.png new file mode 100644 index 0000000000000000000000000000000000000000..9575ebbc9ac4256e1dc8ea75130cc9130905948b GIT binary patch literal 329 zcmV-P0k-~$P)Px$14%?dR5(v#WS|f*QmCJSwg%WM*8K;$@ZkL>oEG7f0BMfa&1Dc05Mh{nxE`k= zSPcMa&b4i1khlBA@bC~D!_G%r8P45V#&Gt@G7R+?0_d9GeR#uQ=*Pz}Ysqe`hM*V# z(+rClWEb3ec#1(y-VDPKxB)OfgKPsi8)Wn8PbV4DVq6){Z~6phH%^+$@ci8wxOY$t z0QnoF5fpGR+hGQQT!qaQa085GqW&AHL@~I_d4n~B{A|i+4z?LagA958?iO|zfFzL( zf!PeR6(kQbXy&i#galM43a`>;P8am3Sy&2CC-EdGYA$V*wO$