From c73f7289a4e6fe60be5aa8f623c504cd62020ab5 Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 7 Jun 2023 18:51:25 +0200 Subject: [PATCH] [Feature] Datagen will generate Loot Tables for End-Village chests --- .../datagen/betterend/BetterEndDatagen.java | 2 + .../recipes/EndChestLootTableProvider.java | 209 ++++++++++++++++++ 2 files changed, 211 insertions(+) create mode 100644 src/main/java/org/betterx/datagen/betterend/recipes/EndChestLootTableProvider.java diff --git a/src/main/java/org/betterx/datagen/betterend/BetterEndDatagen.java b/src/main/java/org/betterx/datagen/betterend/BetterEndDatagen.java index 485191e8..54ba3141 100644 --- a/src/main/java/org/betterx/datagen/betterend/BetterEndDatagen.java +++ b/src/main/java/org/betterx/datagen/betterend/BetterEndDatagen.java @@ -1,6 +1,7 @@ package org.betterx.datagen.betterend; import org.betterx.datagen.betterend.advancement.EndAdvancementDataProvider; +import org.betterx.datagen.betterend.recipes.EndChestLootTableProvider; import org.betterx.datagen.betterend.recipes.EndRecipeDataProvider; import org.betterx.datagen.betterend.worldgen.EndBiomesDataProvider; import org.betterx.datagen.betterend.worldgen.EndRegistriesDataProvider; @@ -27,6 +28,7 @@ public class BetterEndDatagen implements DataGeneratorEntrypoint { pack.addProvider(EndAdvancementDataProvider::new); pack.addProvider(EndBlockTagDataProvider::new); pack.addProvider(EndItemTagDataProvider::new); + pack.addProvider(EndChestLootTableProvider::new); } diff --git a/src/main/java/org/betterx/datagen/betterend/recipes/EndChestLootTableProvider.java b/src/main/java/org/betterx/datagen/betterend/recipes/EndChestLootTableProvider.java new file mode 100644 index 00000000..b0c5a073 --- /dev/null +++ b/src/main/java/org/betterx/datagen/betterend/recipes/EndChestLootTableProvider.java @@ -0,0 +1,209 @@ +package org.betterx.datagen.betterend.recipes; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; +import org.betterx.betterend.registry.EndItems; +import org.betterx.betterend.registry.EndTemplates; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.SimpleFabricLootTableProvider; + +import java.util.function.BiConsumer; + +public class EndChestLootTableProvider extends SimpleFabricLootTableProvider { + + public EndChestLootTableProvider( + FabricDataOutput output + ) { + super(output, LootContextParamSets.CHEST); + } + + //TODO: 1.20 - find where Betterend Injects Loot into chests and make it conform to regular minecraft + public static final ResourceLocation VILLAGE_LOOT = BetterEnd.makeID("chests/end_village_loot"); + public static final ResourceLocation VILLAGE_TEMPLATE_LOOT = BetterEnd.makeID("chests/end_village_template_loot"); + public static final ResourceLocation VILLAGE_BONUS_LOOT = BetterEnd.makeID("chests/end_village_bonus_loot"); + + + @Override + public void generate(BiConsumer biConsumer) { + biConsumer.accept( + VILLAGE_LOOT, + LootTable.lootTable() + .withPool(simpleVillageLoot()) + .withPool(plateUpgradeLootPool()) + ); + + biConsumer.accept( + VILLAGE_TEMPLATE_LOOT, + LootTable.lootTable() + .withPool(simpleVillageLoot()) + .withPool(handleLootPool()) + .withPool(leatherHandleLootPool()) + .withPool(plateUpgradeLootPool()) + .withPool(upgradeLootPool()) + ); + + biConsumer.accept( + VILLAGE_BONUS_LOOT, + LootTable.lootTable() + .withPool(leatherHandleLootPool()) + .withPool(plateUpgradeLootPool()) + .withPool(villageBonusLoot()) + .withPool(elytraLoot(0.2f)) + ); + } + + private LootPool.Builder upgradeLootPool() { + return LootPool + .lootPool() + .setRolls(UniformGenerator.between(1, 2)) + .add(LootItem + .lootTableItem(EndTemplates.THALLASIUM_UPGRADE) + .setWeight(8) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(EndTemplates.TERMINITE_UPGRADE) + .setWeight(4) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(EndTemplates.AETERNIUM_UPGRADE) + .setWeight(2) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(EndTemplates.NETHERITE_UPGRADE) + .setWeight(8) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ); + } + + private LootPool.Builder plateUpgradeLootPool() { + return LootPool + .lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem + .lootTableItem(EndTemplates.PLATE_UPGRADE) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 2))) + .when(LootItemRandomChanceCondition.randomChance(0.70F)) + ); + } + + private LootPool.Builder leatherHandleLootPool() { + return LootPool + .lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem + .lootTableItem(EndTemplates.LEATHER_HANDLE_ATTACHMENT) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + .when(LootItemRandomChanceCondition.randomChance(0.75F)) + ); + } + + private LootPool.Builder handleLootPool() { + return LootPool + .lootPool() + .setRolls(ConstantValue.exactly(1)) + .add(LootItem + .lootTableItem(EndTemplates.HANDLE_ATTACHMENT) + .setWeight(8) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4))) + ) + .add(LootItem + .lootTableItem(EndTemplates.TOOL_ASSEMBLY) + .setWeight(2) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ); + } + + private LootPool.Builder villageBonusLoot() { + return LootPool + .lootPool() + .setRolls(UniformGenerator.between(1, 2)) + .add(LootItem + .lootTableItem(EndItems.AETERNIUM_INGOT) + .setWeight(8) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4))) + ) + .add(LootItem + .lootTableItem(EndBlocks.FLAVOLITE_RUNED_ETERNAL) + .setWeight(4) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(EndItems.ETERNAL_CRYSTAL) + .setWeight(1) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(Items.SHULKER_SHELL) + .setWeight(1) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(2, 4))) + ); + } + + private LootPool.Builder elytraLoot(float chance) { + return LootPool + .lootPool() + .setRolls(UniformGenerator.between(1, 3)) + .add(LootItem + .lootTableItem(Items.ELYTRA) + .setWeight(1) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ).add(LootItem + .lootTableItem(Items.FIREWORK_ROCKET) + .setWeight(8) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(4, 8))) + ) + .when(LootItemRandomChanceCondition.randomChance(chance)); + } + + private LootPool.Builder simpleVillageLoot() { + return LootPool + .lootPool() + .setRolls(UniformGenerator.between(1, 3)) + .add(LootItem + .lootTableItem(EndItems.LEATHER_WRAPPED_STICK) + .setWeight(10) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(2, 5))) + ) + .add(LootItem + .lootTableItem(Items.ENDER_PEARL) + .setWeight(9) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 5))) + ) + .add(LootItem + .lootTableItem(EndItems.SHADOW_BERRY_COOKED) + .setWeight(8) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4))) + ) + .add(LootItem + .lootTableItem(EndItems.BLOSSOM_BERRY_JELLY) + .setWeight(4) + .apply(SetItemCountFunction.setCount(UniformGenerator.between(1, 4))) + ) + .add(LootItem + .lootTableItem(EndBlocks.THALLASIUM.shovelHead) + .setWeight(2) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ) + .add(LootItem + .lootTableItem(Blocks.ENDER_CHEST) + .setWeight(1) + .apply(SetItemCountFunction.setCount(ConstantValue.exactly(1))) + ); + } +}