🇬🇧 English
🇬🇧 English
Appearance
🇬🇧 English
🇬🇧 English
Appearance
This page is written for version:
1.21
This page is written for version:
1.21
PREREQUISITES
Make sure you've completed the datagen setup process first.
You will need different providers (classes) for blocks, chests, and entities. Remember to add them all to your pack in your DataGeneratorEntrypoint
within the onInitializeDataGenerator
method.
pack.addProvider(FabricDocsReferenceBlockLootTableProvider::new);
pack.addProvider(FabricDocsReferenceChestLootTableProvider::new);
Loot tables define what you get from breaking a block (not including contents, like in chests), killing an entity, or opening a newly-generated container. Each loot table has pools from which items are selected. Loot tables also have functions, which modify the resulting loot in some way.
Loot pools have entries, conditions, functions, rolls, and bonus rolls. Entries are groups, sequences, or possibilities of items, or just items. Conditions are things that are tested for in the world, such as enchantments on a tool or a random chance. The minimum number of entries chosen by a pool are called rolls, and anything over that is called a bonus roll.
In order for blocks to drop items - including itself - we need to make a loot table. Create a class that extends FabricBlockLootTableProvider
:
public class FabricDocsReferenceBlockLootTableProvider extends FabricBlockLootTableProvider {
protected FabricDocsReferenceBlockLootTableProvider(FabricDataOutput dataOutput, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
super(dataOutput, registryLookup);
}
@Override
public void generate() {
}
}
Make sure to add this provider to your pack!
There's a lot of helper methods available to help you build your loot tables. We won't go over all of them, so make sure to check them out in your IDE.
Let's add a few drops in the generate
method:
// Make condensed dirt drop its block item.
// Also adds the condition that it survives the explosion that broke it, if applicable,
addDrop(ModBlocks.CONDENSED_DIRT);
// Make prismarine lamps drop themselves with silk touch only
addDropWithSilkTouch(ModBlocks.PRISMARINE_LAMP);
// Make condensed oak logs drop between 7 and 9 oak logs
addDrop(ModBlocks.CONDENSED_OAK_LOG, LootTable.builder().pool(addSurvivesExplosionCondition(Items.OAK_LOG, LootPool.builder()
.rolls(new UniformLootNumberProvider(new ConstantLootNumberProvider(7), new ConstantLootNumberProvider(9)))
.with(ItemEntry.builder(Items.OAK_LOG))))
);
Chest loot is a little bit tricker than block loot. Create a class that extends SimpleFabricLootTableProvider
similar to the example below and add it to your pack.
public class FabricDocsReferenceChestLootTableProvider extends SimpleFabricLootTableProvider {
public FabricDocsReferenceChestLootTableProvider(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registryLookup) {
super(output, registryLookup, LootContextTypes.CHEST);
}
@Override
public void accept(BiConsumer<RegistryKey<LootTable>, LootTable.Builder> lootTableBiConsumer) {
}
}
We'll need a RegistryKey<LootTable>
for our loot table. Let's put that in a new class called ModLootTables
. Make sure this is in your main
source set if you're using split sources.
public class ModLootTables {
public static RegistryKey<LootTable> TEST_CHEST_LOOT = RegistryKey.of(RegistryKeys.LOOT_TABLE, Identifier.of(FabricDocsReference.MOD_ID, "chests/test_loot"));
}
Then, we can generate a loot table inside the generate
method of your provider.
lootTableBiConsumer.accept(ModLootTables.TEST_CHEST_LOOT, LootTable.builder()
.pool(LootPool.builder() // One pool
.rolls(ConstantLootNumberProvider.create(2.0f)) // That has two rolls
.with(ItemEntry.builder(Items.DIAMOND) // With an entry that has diamond(s)
.apply(SetCountLootFunction.builder(ConstantLootNumberProvider.create(1.0f)))) // One diamond
.with(ItemEntry.builder(Items.DIAMOND_SWORD) // With an entry that has a plain diamond sword
)
));