From 2ee2f43d8c6a047286e6d7589d5f9032db7bdab0 Mon Sep 17 00:00:00 2001 From: Wet Noodle Date: Fri, 17 Jan 2025 21:20:47 -0500 Subject: [PATCH 01/10] Loot pool modifier start --- .../frozenblock/lib/loot/MutableLootPool.java | 69 +++++++++++++++ .../lib/loot/MutableLootTable.java | 88 +++++++++++++++++++ src/main/resources/frozenlib.accesswidener | 22 +++++ 3 files changed, 179 insertions(+) create mode 100644 src/main/java/net/frozenblock/lib/loot/MutableLootPool.java create mode 100644 src/main/java/net/frozenblock/lib/loot/MutableLootTable.java diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java new file mode 100644 index 000000000..6611a836b --- /dev/null +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -0,0 +1,69 @@ +package net.frozenblock.lib.loot; + +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; +import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import java.util.ArrayList; + +public class MutableLootPool { + public ArrayList entries = new ArrayList<>(); + public ArrayList conditions = new ArrayList<>(); + public ArrayList functions = new ArrayList<>(); + public NumberProvider rolls = ConstantValue.exactly(1.0F); + public NumberProvider bonusRolls = ConstantValue.exactly(0.0F); + + public MutableLootPool(LootPool lootPool) { + entries.addAll(lootPool.entries); + conditions.addAll(lootPool.conditions); + functions.addAll(lootPool.functions); + rolls = lootPool.rolls; + bonusRolls = lootPool.bonusRolls; + } + + public LootPool build() { + LootPool.Builder builder = LootPool.lootPool(); +// entries.forEach(entry -> ((LootPoolBuilderInterface) builder).wilderWild$add(entry)); + entries.forEach(builder.entries::add); +// conditions.forEach(condition -> ((LootPoolBuilderInterface) builder).wilderWild$when(condition)); + conditions.forEach(builder.conditions::add); +// functions.forEach(function -> ((LootPoolBuilderInterface) builder).wilderWild$apply(function)); + functions.forEach(builder.functions::add); + builder.setRolls(rolls); + builder.setBonusRolls(bonusRolls); + return builder.build(); + } + + /** + * Adds one item to the loot pool + * + * @param item item to add + * @param weight how likely the item is to get drawn from the pool + * @param builder idk lol + * @return this + */ + public MutableLootPool add(ItemLike item, int weight, LootItemFunction.Builder builder) { + entries.add(LootItem.lootTableItem(item).setWeight(weight).apply(builder).build()); + return this; + } + + /** + * Returns if the loot pool contains the given item + * + * @param item item to check for + * @return if item was found + */ + public boolean hasItem(Item item) { + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (item.equals(lootItem.item.value())) return true; + } + } + return false; + } +} diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java new file mode 100644 index 000000000..c8318b555 --- /dev/null +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -0,0 +1,88 @@ +package net.frozenblock.lib.loot; + +import net.fabricmc.fabric.api.loot.v3.LootTableSource; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.LootPool; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class MutableLootTable { + private ArrayList pools = new ArrayList<>(); + private ArrayList functions = new ArrayList<>(); + private LootContextParamSet paramSet = LootTable.DEFAULT_PARAM_SET; + private ResourceLocation randomSequence; + + public MutableLootTable(LootTable table) { + pools = createLootPools(table.pools); + functions.addAll(table.functions); + paramSet = table.getParamSet(); + randomSequence = table.randomSequence.orElse(null); + } + + public static @Nullable MutableLootTable getMutable(ResourceKey lootTableKey, ResourceKey id, LootTable lootTable) { + if (lootTableKey.equals(id)) { + return new MutableLootTable(lootTable); + } else return null; + } + + public static @Nullable MutableLootTable getMutable(ResourceKey lootTableKey, ResourceKey id, LootTable lootTable, LootTableSource source) { + if (source.isBuiltin()) { + return getMutable(lootTableKey, id, lootTable); + } else return null; + } + + public LootTable build() { + LootTable.Builder builder = LootTable.lootTable(); + builder.setParamSet(paramSet); + builder.setRandomSequence(randomSequence); +// pools.forEach(mPool -> ((LootTableBuilderInterface) builder).wilderWild$withPool(mPool.build())); + pools.forEach(mPool -> builder.pools.add(mPool.build())); +// functions.forEach(function -> ((LootTableBuilderInterface) builder).wilderWild$apply(function)); + functions.forEach(builder.functions::add); + return builder.build(); + } + + + /** + * Runs the consumer on each pool + * + * @return this + */ + public MutableLootTable modifyPools(Consumer consumer) { + pools.forEach(consumer); + return this; + } + + /** + * Runs the consumer on each pool that matches the condition + * + * @return this + */ + public MutableLootTable modifyPools(Predicate condition, Consumer consumer) { + pools.forEach(pool -> { + if (condition.test(pool)) { + consumer.accept(pool); + } + }); + return this; + } + + /** + * Converts a list of loot pools to an array list of mutable loot pools + * + * @param lootPoolList loot pools to copy + * @return array list of converted loot pools from input + */ + private static ArrayList createLootPools(List lootPoolList) { + ArrayList lootPools = new ArrayList<>(); + lootPoolList.forEach(pool -> lootPools.add(new MutableLootPool(pool))); + return lootPools; + } +} diff --git a/src/main/resources/frozenlib.accesswidener b/src/main/resources/frozenlib.accesswidener index d3ceb9d64..a0ed24d54 100644 --- a/src/main/resources/frozenlib.accesswidener +++ b/src/main/resources/frozenlib.accesswidener @@ -171,6 +171,28 @@ transitive-accessible class net/minecraft/world/level/levelgen/SurfaceRules$Laz # Placement Modifiers transitive-accessible field net/minecraft/world/level/levelgen/placement/PlacementContext level Lnet/minecraft/world/level/WorldGenLevel; +# Loot Table +accessible field net/minecraft/world/level/storage/loot/LootTable pools Ljava/util/List; +accessible field net/minecraft/world/level/storage/loot/LootTable functions Ljava/util/List; +accessible field net/minecraft/world/level/storage/loot/LootTable randomSequence Ljava/util/Optional; + +# Loot Table Builder +accessible field net/minecraft/world/level/storage/loot/LootTable$Builder pools Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootTable$Builder functions Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootTable$Builder paramSet Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootTable$Builder randomSequence Lcom/google/common/collect/ImmutableList$Builder; + +#Loot Pool + +accessible field net/minecraft/world/level/storage/loot/LootPool$Builder entries Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootPool$Builder conditions Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootPool$Builder functions Lcom/google/common/collect/ImmutableList$Builder; +accessible field net/minecraft/world/level/storage/loot/LootPool$Builder rolls Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider; +accessible field net/minecraft/world/level/storage/loot/LootPool$Builder bonusRolls Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider; + +#Loot Item +accessible field net/minecraft/world/level/storage/loot/entries/LootItem item Lnet/minecraft/core/Holder; + # QuiltMC Resource Reloaders transitive-accessible class net/minecraft/client/gui/screens/worldselection/CreateWorldScreen$DataPackReloadCookie transitive-accessible class net/minecraft/resources/RegistryDataLoader$LoadingFunction From d23832b244d8ea63d055f9144574794d95c96157 Mon Sep 17 00:00:00 2001 From: Wet Noodle Date: Fri, 17 Jan 2025 22:09:42 -0500 Subject: [PATCH 02/10] Added some tests, more actions, conditions, and some cleaning --- .../lib/loot/LootTableModifier.java | 28 ++++ .../frozenblock/lib/loot/MutableLootPool.java | 74 +++++++++- .../lib/loot/MutableLootTable.java | 33 ++++- .../lib/testmod/FrozenTestMain.java | 128 +++++++----------- .../lib/testmod/registry/FTLootTables.java | 27 ++++ 5 files changed, 208 insertions(+), 82 deletions(-) create mode 100644 src/main/java/net/frozenblock/lib/loot/LootTableModifier.java create mode 100644 src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java diff --git a/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java new file mode 100644 index 000000000..2efd74e39 --- /dev/null +++ b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java @@ -0,0 +1,28 @@ +package net.frozenblock.lib.loot; + +import net.fabricmc.fabric.api.loot.v3.LootTableEvents; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.storage.loot.LootTable; + +public class LootTableModifier { + public static void editTable(ResourceKey targetLootTable, boolean requiresBuiltIn, Edit listener) { + LootTableEvents.Replace temp = (id, lootTable, source, registries) -> { + if ((requiresBuiltIn && !source.isBuiltin()) || !targetLootTable.equals(id)) return null; + MutableLootTable mutableLootTable = new MutableLootTable(lootTable); + listener.editLootTable(id, mutableLootTable); + return mutableLootTable.build(); + }; + LootTableEvents.REPLACE.register(temp); + } + + @FunctionalInterface + public interface Edit { + /** + * Edits loot tables. + * + * @param id the loot table key + * @param mutableLootTable the mutable copy of the loot table + */ + void editLootTable(ResourceKey id, MutableLootTable mutableLootTable); + } +} diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java index 6611a836b..cea1df261 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -1,5 +1,6 @@ package net.frozenblock.lib.loot; +import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.storage.loot.LootPool; @@ -10,6 +11,7 @@ import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; import java.util.ArrayList; +import java.util.function.Predicate; public class MutableLootPool { public ArrayList entries = new ArrayList<>(); @@ -28,11 +30,8 @@ public MutableLootPool(LootPool lootPool) { public LootPool build() { LootPool.Builder builder = LootPool.lootPool(); -// entries.forEach(entry -> ((LootPoolBuilderInterface) builder).wilderWild$add(entry)); entries.forEach(builder.entries::add); -// conditions.forEach(condition -> ((LootPoolBuilderInterface) builder).wilderWild$when(condition)); conditions.forEach(builder.conditions::add); -// functions.forEach(function -> ((LootPoolBuilderInterface) builder).wilderWild$apply(function)); functions.forEach(builder.functions::add); builder.setRolls(rolls); builder.setBonusRolls(bonusRolls); @@ -66,4 +65,73 @@ public boolean hasItem(Item item) { } return false; } + + /** + * Returns if the loot pool contains an item that matches the predicate + * + * @param predicate condition to check for + * @return if item was found + */ + public boolean hasItem(Predicate predicate) { + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (predicate.test(lootItem.item.value())) return true; + } + } + return false; + } + + /** + * Returns if the loot pool contains an item with the given tag + * + * @param itemTagKey item tag to check for + * @return if item was found + */ + public boolean hasItem(TagKey itemTagKey) { + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (lootItem.item.value().builtInRegistryHolder().is(itemTagKey)) return true; + } + } + return false; + } + + /** + * Returns if the loot pool contains any of the given items + * + * @param items items to check for + * @return if any of the items were found + */ + public boolean hasAnyItems(Item... items) { + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + for (Item item : items) { + if (item.equals(lootItem.item.value())) return true; + } + } + } + return false; + } + + /** + * Returns if the loot table contains all the given items + * + * @param items items to check for + * @return if all of the items were found + */ + public boolean hasAllItems(Item... items) { + for (Item item : items) { + boolean found = false; + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (item.equals(lootItem.item.value())) { + found = true; + break; + } + } + } + if (!found) return false; + } + return true; + } } diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java index c8318b555..02c2634d4 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -3,6 +3,7 @@ import net.fabricmc.fabric.api.loot.v3.LootTableSource; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.functions.LootItemFunction; @@ -42,9 +43,7 @@ public LootTable build() { LootTable.Builder builder = LootTable.lootTable(); builder.setParamSet(paramSet); builder.setRandomSequence(randomSequence); -// pools.forEach(mPool -> ((LootTableBuilderInterface) builder).wilderWild$withPool(mPool.build())); pools.forEach(mPool -> builder.pools.add(mPool.build())); -// functions.forEach(function -> ((LootTableBuilderInterface) builder).wilderWild$apply(function)); functions.forEach(builder.functions::add); return builder.build(); } @@ -85,4 +84,34 @@ private static ArrayList createLootPools(List lootPoo lootPoolList.forEach(pool -> lootPools.add(new MutableLootPool(pool))); return lootPools; } + + /** + * Returns if a pool has the given item + * + * @param item item to check for + * @return predicate that checks if the pool has the given item + */ + public static Predicate has(Item item) { + return lootPool -> lootPool.hasItem(item); + } + + /** + * Returns if a pool has any of the given items + * + * @param items items to check for + * @return predicate that checks if the pool has any of the given items + */ + public static Predicate hasAny(Item... items) { + return lootPool -> lootPool.hasAnyItems(items); + } + + /** + * Returns if a pool has all the given items + * + * @param items items to check for + * @return predicate that checks if the pool has all the given items + */ + public static Predicate hasAll(Item... items) { + return lootPool -> lootPool.hasAllItems(items); + } } diff --git a/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java b/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java index c65f7e908..d0c9afb0d 100644 --- a/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java +++ b/src/testmod/java/net/frozenblock/lib/testmod/FrozenTestMain.java @@ -17,93 +17,67 @@ package net.frozenblock.lib.testmod; -import java.util.List; import net.fabricmc.api.ModInitializer; -/* -import net.fabricmc.frozenblock.datafixer.api.FabricDataFixerBuilder; -import net.fabricmc.frozenblock.datafixer.api.FabricDataFixes; -import net.fabricmc.frozenblock.datafixer.api.SimpleFixes; - */ -import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; -import net.frozenblock.lib.advancement.api.AdvancementAPI; -import net.frozenblock.lib.advancement.api.AdvancementEvents; -import net.frozenblock.lib.block.api.tick.BlockScheduledTicks; -import net.frozenblock.lib.gravity.api.GravityAPI; -import net.frozenblock.lib.gravity.api.GravityBelt; -import net.frozenblock.lib.gravity.api.functions.AbsoluteGravityFunction; -import net.frozenblock.lib.testmod.config.TestConfig; -import net.minecraft.advancements.Advancement; -import net.minecraft.advancements.AdvancementRequirements; -import net.minecraft.advancements.critereon.LocationPredicate; -import net.minecraft.advancements.critereon.PlayerTrigger; -import net.minecraft.core.Holder; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; +import net.frozenblock.lib.testmod.registry.FTLootTables; import net.minecraft.resources.ResourceLocation; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.biome.Biomes; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.storage.loot.BuiltInLootTables; -import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class FrozenTestMain implements ModInitializer { - public static final String MOD_ID = "frozenlib_testmod"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - @Override - public void onInitialize() { - applyDataFixes(FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow()); - LOGGER.info("The test toggle value is {}", TestConfig.get().testToggle); - LOGGER.info("The test vec3 value is {}", TestConfig.get().typedVecList); - Holder sound = TestConfig.get().randomSound.value(); - LOGGER.info("The test soundevent value is {} and its ID is {}", sound, sound.unwrapKey().orElseThrow().location()); - - BlockScheduledTicks.TICKS.put(Blocks.DIAMOND_BLOCK, (state, world, pos, random) -> world.setBlock(pos, - Blocks.BEDROCK.defaultBlockState(), 3)); + public static final String MOD_ID = "frozenlib_testmod"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - GravityAPI.MODIFICATIONS.register((ctx) -> { - if (ctx.y < 300 && ctx.entity instanceof Player) { - ctx.gravity = new Vec3(0.05, 0.8, 0.05); - } - }); - - GravityAPI.register(Level.OVERWORLD, new GravityBelt<>(300, 319, true, true, new AbsoluteGravityFunction(new Vec3(0.0, 0.1, 0.0)))); - assert GravityAPI.calculateGravity(Level.OVERWORLD, 300).y == 0.1; - - //GravityAPI.register(BuiltinDimensionTypes.OVERWORLD, new GravityBelt<>(0, 192, new InterpolatedGravityFunction(0.1))); - - AdvancementEvents.INIT.register((holder, registries) -> { - Advancement advancement = holder.value(); - switch (holder.id().toString()) { - case "minecraft:story/mine_stone" -> { - AdvancementAPI.addLootTables(advancement, List.of(BuiltInLootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY)); - advancement.rewards.experience = 100; - } - case "minecraft:story/upgrade_tools" -> { - AdvancementAPI.addLootTables(advancement, List.of(ResourceKey.create(Registries.LOOT_TABLE, id("test_loottable")))); - AdvancementAPI.addCriteria( - advancement, - "minecraft:plains", - PlayerTrigger.TriggerInstance.located( - LocationPredicate.Builder.inBiome(registries.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS)) - ) - ); - AdvancementAPI.addRequirementsAsNewList(advancement, AdvancementRequirements.anyOf(List.of("minecraft:plains"))); - advancement.rewards.experience = 1000; - } - default -> {} - } - }); + @Override + public void onInitialize() { + FTLootTables.init(); +// applyDataFixes(FabricLoader.getInstance().getModContainer(MOD_ID).orElseThrow()); +// LOGGER.info("The test toggle value is {}", TestConfig.get().testToggle); +// LOGGER.info("The test vec3 value is {}", TestConfig.get().typedVecList); +// Holder sound = TestConfig.get().randomSound.value(); +// LOGGER.info("The test soundevent value is {} and its ID is {}", sound, sound.unwrapKey().orElseThrow().location()); +// +// BlockScheduledTicks.TICKS.put(Blocks.DIAMOND_BLOCK, (state, world, pos, random) -> world.setBlock(pos, +// Blocks.BEDROCK.defaultBlockState(), 3)); +// GravityAPI.MODIFICATIONS.register((ctx) -> { +// if (ctx.y < 300 && ctx.entity instanceof Player) { +// ctx.gravity = new Vec3(0.05, 0.8, 0.05); +// } +// }); +// +// GravityAPI.register(Level.OVERWORLD, new GravityBelt<>(300, 319, true, true, new AbsoluteGravityFunction(new Vec3(0.0, 0.1, 0.0)))); +// assert GravityAPI.calculateGravity(Level.OVERWORLD, 300).y == 0.1; +// +// //GravityAPI.register(BuiltinDimensionTypes.OVERWORLD, new GravityBelt<>(0, 192, new InterpolatedGravityFunction(0.1))); +// +// AdvancementEvents.INIT.register((holder, registries) -> { +// Advancement advancement = holder.value(); +// switch (holder.id().toString()) { +// case "minecraft:story/mine_stone" -> { +// AdvancementAPI.addLootTables(advancement, List.of(BuiltInLootTables.OCEAN_RUIN_WARM_ARCHAEOLOGY)); +// advancement.rewards.experience = 100; +// } +// case "minecraft:story/upgrade_tools" -> { +// AdvancementAPI.addLootTables(advancement, List.of(ResourceKey.create(Registries.LOOT_TABLE, id("test_loottable")))); +// AdvancementAPI.addCriteria( +// advancement, +// "minecraft:plains", +// PlayerTrigger.TriggerInstance.located( +// LocationPredicate.Builder.inBiome(registries.lookupOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS)) +// ) +// ); +// AdvancementAPI.addRequirementsAsNewList(advancement, AdvancementRequirements.anyOf(List.of("minecraft:plains"))); +// advancement.rewards.experience = 1000; +// } +// default -> { +// } +// } +// }); //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_1"), id("ancient_city/city_center/city_center_2")); - //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_2"), id("ancient_city/city_center/city_center_2")); - //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_3"), id("ancient_city/city_center/city_center_2")); - } + //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_2"), id("ancient_city/city_center/city_center_2")); + //StructurePoolElementIdReplacements.resourceLocationReplacements.put(new ResourceLocation("ancient_city/city_center/city_center_3"), id("ancient_city/city_center/city_center_2")); + } private static final int DATA_VERSION = 1; diff --git a/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java new file mode 100644 index 000000000..fe2a67c11 --- /dev/null +++ b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java @@ -0,0 +1,27 @@ +package net.frozenblock.lib.testmod.registry; + +import net.frozenblock.lib.loot.LootTableModifier; +import net.frozenblock.lib.loot.MutableLootTable; +import net.frozenblock.lib.testmod.FrozenTestMain; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.storage.loot.BuiltInLootTables; +import net.minecraft.world.level.storage.loot.functions.SetItemCountFunction; +import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator; + +public final class FTLootTables { + private FTLootTables() { + throw new UnsupportedOperationException("FTLootTables only supports static declarations."); + } + + public static void init() { + FrozenTestMain.LOGGER.info("Registering Loot Table Modifications for FrozenTest."); + //BONUS CHEST + LootTableModifier.editTable( + BuiltInLootTables.SPAWN_BONUS_CHEST, false, + (id, mutableLootTable) -> mutableLootTable.modifyPools( + MutableLootTable.has(Items.ACACIA_LOG), + (lootPool) -> lootPool.add(Items.DIAMOND_BLOCK, 3, SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 3.0F))) + ) + ); + } +} From 52ce06107b9ac9cafd6282a55adb837fc42a1269 Mon Sep 17 00:00:00 2001 From: Wet Noodle Date: Fri, 17 Jan 2025 22:22:41 -0500 Subject: [PATCH 03/10] Implemented remove() --- .../frozenblock/lib/loot/MutableLootPool.java | 84 +++++++++++++++++-- .../lib/loot/MutableLootTable.java | 8 +- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java index cea1df261..00b1e5432 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -1,5 +1,7 @@ package net.frozenblock.lib.loot; +import java.util.ArrayList; +import java.util.function.Predicate; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; @@ -8,17 +10,14 @@ import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer; import net.minecraft.world.level.storage.loot.functions.LootItemFunction; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; -import net.minecraft.world.level.storage.loot.providers.number.ConstantValue; import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; -import java.util.ArrayList; -import java.util.function.Predicate; public class MutableLootPool { public ArrayList entries = new ArrayList<>(); public ArrayList conditions = new ArrayList<>(); public ArrayList functions = new ArrayList<>(); - public NumberProvider rolls = ConstantValue.exactly(1.0F); - public NumberProvider bonusRolls = ConstantValue.exactly(0.0F); + public NumberProvider rolls; + public NumberProvider bonusRolls; public MutableLootPool(LootPool lootPool) { entries.addAll(lootPool.entries); @@ -51,6 +50,81 @@ public MutableLootPool add(ItemLike item, int weight, LootItemFunction.Builder b return this; } + /** + * Adds one or more items to the loot pool with the same weight + * + * @param items items to add + * @param weight how likely the items are to get drawn from the pool + * @param builder idk lol + * @return this + */ + public MutableLootPool addAll(int weight, LootItemFunction.Builder builder, ItemLike... items) { + for (ItemLike item : items) { + entries.add(LootItem.lootTableItem(item).setWeight(weight).apply(builder).build()); + } + return this; + } + + public MutableLootPool remove(ItemLike item) { + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (item.equals(lootItem.item.value())) { + entries.remove(entryContainer); + return this; + } + } + } + // Failed to remove item from the loot pool. + return this; + } + + public MutableLootPool remove(ItemLike... items) { + ArrayList toRemove = new ArrayList<>(); + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + for (ItemLike item : items) { + if (item.equals(lootItem.item.value())) { + toRemove.add(entryContainer); + } + } + } + } + for (LootPoolEntryContainer entryContainer : toRemove) { + entries.remove(entryContainer); + } + return this; + } + + public MutableLootPool remove(TagKey tag) { + ArrayList toRemove = new ArrayList<>(); + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (lootItem.item.value().builtInRegistryHolder().is(tag)) { + toRemove.add(entryContainer); + } + } + } + for (LootPoolEntryContainer entryContainer : toRemove) { + entries.remove(entryContainer); + } + return this; + } + + public MutableLootPool remove(Predicate predicate) { + ArrayList toRemove = new ArrayList<>(); + for (LootPoolEntryContainer entryContainer : entries) { + if (entryContainer instanceof LootItem lootItem) { + if (predicate.test(lootItem.item.value())) { + toRemove.add(entryContainer); + } + } + } + for (LootPoolEntryContainer entryContainer : toRemove) { + entries.remove(entryContainer); + } + return this; + } + /** * Returns if the loot pool contains the given item * diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java index 02c2634d4..ec4fd3f5e 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -15,10 +15,10 @@ import java.util.function.Predicate; public class MutableLootTable { - private ArrayList pools = new ArrayList<>(); - private ArrayList functions = new ArrayList<>(); - private LootContextParamSet paramSet = LootTable.DEFAULT_PARAM_SET; - private ResourceLocation randomSequence; + private final ArrayList pools; + private final ArrayList functions = new ArrayList<>(); + private final LootContextParamSet paramSet; + private final ResourceLocation randomSequence; public MutableLootTable(LootTable table) { pools = createLootPools(table.pools); From 56e5f25ea75e3702381702175c9c8edb79ecb49c Mon Sep 17 00:00:00 2001 From: Wet Noodle Date: Sat, 18 Jan 2025 19:50:00 -0500 Subject: [PATCH 04/10] Added replace functionality --- .../frozenblock/lib/loot/MutableLootItem.java | 77 +++++++++++++++++++ .../frozenblock/lib/loot/MutableLootPool.java | 15 ++++ src/main/resources/frozenlib.accesswidener | 13 +++- .../lib/testmod/registry/FTLootTables.java | 10 +++ 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/frozenblock/lib/loot/MutableLootItem.java diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java new file mode 100644 index 000000000..210d26ac2 --- /dev/null +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java @@ -0,0 +1,77 @@ +package net.frozenblock.lib.loot; + +import java.util.List; +import net.minecraft.core.Holder; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.storage.loot.entries.LootItem; +import net.minecraft.world.level.storage.loot.functions.LootItemFunction; +import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; + +public class MutableLootItem { + public final List conditions; + public int weight = LootItem.DEFAULT_WEIGHT; + public int quality = LootItem.DEFAULT_QUALITY; + public final List functions; + public Holder item; + + public MutableLootItem(LootItem original) { + this.conditions = original.conditions; + this.weight = original.weight; + this.quality = original.quality; + this.functions = original.functions; + this.item = original.item; + } + + public MutableLootItem(Holder item, int weight, int quality, List conditions, List functions) { + this.item = item; + this.conditions = conditions; + this.weight = weight; + this.quality = quality; + this.functions = functions; + } + + public MutableLootItem(ItemLike item, int weight, int quality, List conditions, List functions) { + this.item = item.asItem().builtInRegistryHolder(); + this.conditions = conditions; + this.weight = weight; + this.quality = quality; + this.functions = functions; + } + + public LootItem build() { + return new LootItem(item, weight, quality, conditions, functions); + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public int getQuality() { + return quality; + } + + public void setQuality(int quality) { + this.quality = quality; + } + + public Holder getItemHolder() { + return item; + } + + public Item getItem() { + return item.value(); + } + + public void setItem(Holder item) { + this.item = item; + } + + public void setItem(ItemLike item) { + this.item = item.asItem().builtInRegistryHolder(); + } +} diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java index 00b1e5432..bbbdbf8d5 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -125,6 +125,21 @@ public MutableLootPool remove(Predicate predicate) { return this; } + public MutableLootPool replace(ItemLike original, ItemLike replacement) { +// for (LootPoolEntryContainer entryContainer : entries) { + for (int i = 0; i < entries.size(); i++) { + LootPoolEntryContainer entryContainer = entries.get(i); + if (entryContainer instanceof LootItem lootItem) { + if (original.equals(lootItem.item.value())) { + MutableLootItem mutableLootItem = new MutableLootItem(lootItem); + mutableLootItem.setItem(replacement); + entries.set(i, mutableLootItem.build()); + } + } + } + return this; + } + /** * Returns if the loot pool contains the given item * diff --git a/src/main/resources/frozenlib.accesswidener b/src/main/resources/frozenlib.accesswidener index a0ed24d54..6886b1b3a 100644 --- a/src/main/resources/frozenlib.accesswidener +++ b/src/main/resources/frozenlib.accesswidener @@ -183,15 +183,26 @@ accessible field net/minecraft/world/level/storage/loot/LootTable$Builder paramS accessible field net/minecraft/world/level/storage/loot/LootTable$Builder randomSequence Lcom/google/common/collect/ImmutableList$Builder; #Loot Pool - accessible field net/minecraft/world/level/storage/loot/LootPool$Builder entries Lcom/google/common/collect/ImmutableList$Builder; accessible field net/minecraft/world/level/storage/loot/LootPool$Builder conditions Lcom/google/common/collect/ImmutableList$Builder; accessible field net/minecraft/world/level/storage/loot/LootPool$Builder functions Lcom/google/common/collect/ImmutableList$Builder; accessible field net/minecraft/world/level/storage/loot/LootPool$Builder rolls Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider; accessible field net/minecraft/world/level/storage/loot/LootPool$Builder bonusRolls Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider; +#Loot Pool Entry Container +accessible method net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer (Ljava/util/List;)V +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer conditions Ljava/util/List; +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer compositeCondition Ljava/util/function/Predicate; + #Loot Item accessible field net/minecraft/world/level/storage/loot/entries/LootItem item Lnet/minecraft/core/Holder; +accessible method net/minecraft/world/level/storage/loot/entries/LootItem (Lnet/minecraft/core/Holder;IILjava/util/List;Ljava/util/List;)V + +#Loot Pool Singleton Container +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer weight I +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer quality I +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer functions Ljava/util/List; +accessible field net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer compositeFunction Ljava/util/function/BiFunction; # QuiltMC Resource Reloaders transitive-accessible class net/minecraft/client/gui/screens/worldselection/CreateWorldScreen$DataPackReloadCookie diff --git a/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java index fe2a67c11..435338d11 100644 --- a/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java +++ b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java @@ -23,5 +23,15 @@ public static void init() { (lootPool) -> lootPool.add(Items.DIAMOND_BLOCK, 3, SetItemCountFunction.setCount(UniformGenerator.between(1.0F, 3.0F))) ) ); + + //Cold Ocean Ruin Archaeology + LootTableModifier.editTable( + BuiltInLootTables.OCEAN_RUIN_COLD_ARCHAEOLOGY, false, + (id, mutableLootTable) -> mutableLootTable.modifyPools( + MutableLootTable.has(Items.MOURNER_POTTERY_SHERD), + (lootPool) -> lootPool.replace(Items.MOURNER_POTTERY_SHERD, Items.FLOW_POTTERY_SHERD) + ) + ); + } } From 36de85935953fae759ecf68e73548118ca15ae45 Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:21:14 -0500 Subject: [PATCH 05/10] Update PanoramaCommand.java --- .../net/frozenblock/lib/core/client/api/PanoramaCommand.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/frozenblock/lib/core/client/api/PanoramaCommand.java b/src/main/java/net/frozenblock/lib/core/client/api/PanoramaCommand.java index d9e8491a1..73061a608 100644 --- a/src/main/java/net/frozenblock/lib/core/client/api/PanoramaCommand.java +++ b/src/main/java/net/frozenblock/lib/core/client/api/PanoramaCommand.java @@ -38,7 +38,6 @@ public static void register(@NotNull CommandDispatcher { - FrozenSharedConstants.LOGGER.warn("PLAYER HAS ACCESS TO DEV CAMERA AND HAS JUST USED IT"); Minecraft client = Minecraft.getInstance(); File directory = getPanoramaFolderName(new File(client.gameDirectory, "panoramas")); File directory1 = new File(directory, "screenshots"); From 608a0b0a0341bd57ef02ded394fa8356f6ea5428 Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:46:03 -0500 Subject: [PATCH 06/10] Slightly improve javadoc --- .../lib/loot/LootTableModifier.java | 10 ++-- .../frozenblock/lib/loot/MutableLootItem.java | 9 ++-- .../frozenblock/lib/loot/MutableLootPool.java | 8 +-- .../lib/loot/MutableLootTable.java | 49 ++++++++++--------- 4 files changed, 42 insertions(+), 34 deletions(-) diff --git a/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java index 2efd74e39..c8d2ce74c 100644 --- a/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java +++ b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java @@ -5,14 +5,16 @@ import net.minecraft.world.level.storage.loot.LootTable; public class LootTableModifier { + public static void editTable(ResourceKey targetLootTable, boolean requiresBuiltIn, Edit listener) { - LootTableEvents.Replace temp = (id, lootTable, source, registries) -> { + LootTableEvents.Replace modification = (id, lootTable, source, registries) -> { if ((requiresBuiltIn && !source.isBuiltin()) || !targetLootTable.equals(id)) return null; MutableLootTable mutableLootTable = new MutableLootTable(lootTable); listener.editLootTable(id, mutableLootTable); return mutableLootTable.build(); }; - LootTableEvents.REPLACE.register(temp); + + LootTableEvents.REPLACE.register(modification); } @FunctionalInterface @@ -20,8 +22,8 @@ public interface Edit { /** * Edits loot tables. * - * @param id the loot table key - * @param mutableLootTable the mutable copy of the loot table + * @param id The loot table key. + * @param mutableLootTable The mutable copy of the loot table. */ void editLootTable(ResourceKey id, MutableLootTable mutableLootTable); } diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java index 210d26ac2..ad9dfaee0 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java @@ -7,11 +7,12 @@ import net.minecraft.world.level.storage.loot.entries.LootItem; import net.minecraft.world.level.storage.loot.functions.LootItemFunction; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; +import org.jetbrains.annotations.NotNull; public class MutableLootItem { public final List conditions; - public int weight = LootItem.DEFAULT_WEIGHT; - public int quality = LootItem.DEFAULT_QUALITY; + public int weight; + public int quality; public final List functions; public Holder item; @@ -31,7 +32,7 @@ public MutableLootItem(Holder item, int weight, int quality, List conditions, List functions) { + public MutableLootItem(@NotNull ItemLike item, int weight, int quality, List conditions, List functions) { this.item = item.asItem().builtInRegistryHolder(); this.conditions = conditions; this.weight = weight; @@ -71,7 +72,7 @@ public void setItem(Holder item) { this.item = item; } - public void setItem(ItemLike item) { + public void setItem(@NotNull ItemLike item) { this.item = item.asItem().builtInRegistryHolder(); } } diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java index bbbdbf8d5..0bd0c3881 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -11,6 +11,7 @@ import net.minecraft.world.level.storage.loot.functions.LootItemFunction; import net.minecraft.world.level.storage.loot.predicates.LootItemCondition; import net.minecraft.world.level.storage.loot.providers.number.NumberProvider; +import org.jetbrains.annotations.NotNull; public class MutableLootPool { public ArrayList entries = new ArrayList<>(); @@ -19,7 +20,7 @@ public class MutableLootPool { public NumberProvider rolls; public NumberProvider bonusRolls; - public MutableLootPool(LootPool lootPool) { + public MutableLootPool(@NotNull LootPool lootPool) { entries.addAll(lootPool.entries); conditions.addAll(lootPool.conditions); functions.addAll(lootPool.functions); @@ -58,7 +59,7 @@ public MutableLootPool add(ItemLike item, int weight, LootItemFunction.Builder b * @param builder idk lol * @return this */ - public MutableLootPool addAll(int weight, LootItemFunction.Builder builder, ItemLike... items) { + public MutableLootPool addAll(int weight, LootItemFunction.Builder builder, ItemLike @NotNull ... items) { for (ItemLike item : items) { entries.add(LootItem.lootTableItem(item).setWeight(weight).apply(builder).build()); } @@ -126,7 +127,6 @@ public MutableLootPool remove(Predicate predicate) { } public MutableLootPool replace(ItemLike original, ItemLike replacement) { -// for (LootPoolEntryContainer entryContainer : entries) { for (int i = 0; i < entries.size(); i++) { LootPoolEntryContainer entryContainer = entries.get(i); if (entryContainer instanceof LootItem lootItem) { @@ -208,7 +208,7 @@ public boolean hasAnyItems(Item... items) { * @param items items to check for * @return if all of the items were found */ - public boolean hasAllItems(Item... items) { + public boolean hasAllItems(Item @NotNull ... items) { for (Item item : items) { boolean found = false; for (LootPoolEntryContainer entryContainer : entries) { diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java index ec4fd3f5e..3f44f5337 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -8,6 +8,8 @@ import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.functions.LootItemFunction; import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -20,20 +22,20 @@ public class MutableLootTable { private final LootContextParamSet paramSet; private final ResourceLocation randomSequence; - public MutableLootTable(LootTable table) { + public MutableLootTable(@NotNull LootTable table) { pools = createLootPools(table.pools); functions.addAll(table.functions); paramSet = table.getParamSet(); randomSequence = table.randomSequence.orElse(null); } - public static @Nullable MutableLootTable getMutable(ResourceKey lootTableKey, ResourceKey id, LootTable lootTable) { + public static @Nullable MutableLootTable getMutable(@NotNull ResourceKey lootTableKey, ResourceKey id, LootTable lootTable) { if (lootTableKey.equals(id)) { return new MutableLootTable(lootTable); } else return null; } - public static @Nullable MutableLootTable getMutable(ResourceKey lootTableKey, ResourceKey id, LootTable lootTable, LootTableSource source) { + public static @Nullable MutableLootTable getMutable(ResourceKey lootTableKey, ResourceKey id, LootTable lootTable, @NotNull LootTableSource source) { if (source.isBuiltin()) { return getMutable(lootTableKey, id, lootTable); } else return null; @@ -50,9 +52,9 @@ public LootTable build() { /** - * Runs the consumer on each pool + * Runs the consumer on each pool. * - * @return this + * @return This. */ public MutableLootTable modifyPools(Consumer consumer) { pools.forEach(consumer); @@ -60,9 +62,9 @@ public MutableLootTable modifyPools(Consumer consumer) { } /** - * Runs the consumer on each pool that matches the condition + * Runs the consumer on each pool that matches the condition. * - * @return this + * @return This. */ public MutableLootTable modifyPools(Predicate condition, Consumer consumer) { pools.forEach(pool -> { @@ -76,42 +78,45 @@ public MutableLootTable modifyPools(Predicate condition, Consum /** * Converts a list of loot pools to an array list of mutable loot pools * - * @param lootPoolList loot pools to copy - * @return array list of converted loot pools from input + * @param lootPoolList A list of {@link LootPool}s to copy. + * @return An array list of converted loot pools from input. */ - private static ArrayList createLootPools(List lootPoolList) { + private static @NotNull ArrayList createLootPools(@NotNull List lootPoolList) { ArrayList lootPools = new ArrayList<>(); lootPoolList.forEach(pool -> lootPools.add(new MutableLootPool(pool))); return lootPools; } /** - * Returns if a pool has the given item + * Returns if a pool has the given item. * - * @param item item to check for - * @return predicate that checks if the pool has the given item + * @param item The {@link Item}s to check for. + * @return A predicate that checks if the pool has the given item. */ - public static Predicate has(Item item) { + @Contract(pure = true) + public static @NotNull Predicate has(Item item) { return lootPool -> lootPool.hasItem(item); } /** - * Returns if a pool has any of the given items + * Returns if a pool has any of the given items. * - * @param items items to check for - * @return predicate that checks if the pool has any of the given items + * @param items The {@link Item}s to check for. + * @return A predicate that checks if the pool has any of the given items. */ - public static Predicate hasAny(Item... items) { + @Contract(pure = true) + public static @NotNull Predicate hasAny(Item... items) { return lootPool -> lootPool.hasAnyItems(items); } /** - * Returns if a pool has all the given items + * Returns if a pool has all the given items. * - * @param items items to check for - * @return predicate that checks if the pool has all the given items + * @param items The {@link Item}s to check for. + * @return A predicate that checks if the pool has all the given items. */ - public static Predicate hasAll(Item... items) { + @Contract(pure = true) + public static @NotNull Predicate hasAll(Item... items) { return lootPool -> lootPool.hasAllItems(items); } } From 6b6685d24a2dce976dc43e0b842cd2e5a3aaecc5 Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:46:36 -0500 Subject: [PATCH 07/10] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a884ef99d..bfd120676 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,3 +7,4 @@ Put changelog here: ----------------- - Exposed the `structure_upgrade` command to players outside development environments. - Removed the Camera item in favor of the `panorama` command. +- Added the new loot pool modification api, by Kluski42! From 36eca37078dc21275a3dfdd56ed618f36a4c318a Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:47:38 -0500 Subject: [PATCH 08/10] Bump --- CHANGELOG.md | 2 +- gradle.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfd120676..ec3e66417 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,5 +6,5 @@ Put changelog here: ----------------- - Exposed the `structure_upgrade` command to players outside development environments. -- Removed the Camera item in favor of the `panorama` command. +- Removed the Camera item in favor of the new `panorama` client command. - Added the new loot pool modification api, by Kluski42! diff --git a/gradle.properties b/gradle.properties index e049c6d93..5b0cb6e25 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,7 +15,7 @@ min_loader_version=0.16.0 # Mod Properties - mod_version = 1.9.12 + mod_version = 1.9.13 maven_group = net.frozenblock archives_base_name = FrozenLib From 9cfb1d6867a2e85ea5c8351938b7231cb3a03e41 Mon Sep 17 00:00:00 2001 From: AViewFromTheTop Date: Tue, 21 Jan 2025 23:49:59 +0000 Subject: [PATCH 09/10] Apply automatic changes --- .../frozenblock/lib/loot/LootTableModifier.java | 17 +++++++++++++++++ .../frozenblock/lib/loot/MutableLootItem.java | 17 +++++++++++++++++ .../frozenblock/lib/loot/MutableLootPool.java | 17 +++++++++++++++++ .../frozenblock/lib/loot/MutableLootTable.java | 17 +++++++++++++++++ .../lib/testmod/registry/FTLootTables.java | 17 +++++++++++++++++ 5 files changed, 85 insertions(+) diff --git a/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java index c8d2ce74c..9887f70a3 100644 --- a/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java +++ b/src/main/java/net/frozenblock/lib/loot/LootTableModifier.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2025 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.frozenblock.lib.loot; import net.fabricmc.fabric.api.loot.v3.LootTableEvents; diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java index ad9dfaee0..a385b90f8 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootItem.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2025 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.frozenblock.lib.loot; import java.util.List; diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java index 0bd0c3881..711084cf8 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootPool.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2025 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.frozenblock.lib.loot; import java.util.ArrayList; diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java index 3f44f5337..6a272a939 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2025 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.frozenblock.lib.loot; import net.fabricmc.fabric.api.loot.v3.LootTableSource; diff --git a/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java index 435338d11..ba1875375 100644 --- a/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java +++ b/src/testmod/java/net/frozenblock/lib/testmod/registry/FTLootTables.java @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2025 FrozenBlock + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + package net.frozenblock.lib.testmod.registry; import net.frozenblock.lib.loot.LootTableModifier; From b632a9b99ef9b21a01c65c33ed21a2fa60f46aee Mon Sep 17 00:00:00 2001 From: AViewFromTheTop <87103914+AViewFromTheTop@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:51:55 -0500 Subject: [PATCH 10/10] Update MutableLootTable.java --- src/main/java/net/frozenblock/lib/loot/MutableLootTable.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java index 3f44f5337..1a9508286 100644 --- a/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java +++ b/src/main/java/net/frozenblock/lib/loot/MutableLootTable.java @@ -3,11 +3,11 @@ import net.fabricmc.fabric.api.loot.v3.LootTableSource; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.context.ContextKeySet; import net.minecraft.world.item.Item; import net.minecraft.world.level.storage.loot.LootPool; import net.minecraft.world.level.storage.loot.LootTable; import net.minecraft.world.level.storage.loot.functions.LootItemFunction; -import net.minecraft.world.level.storage.loot.parameters.LootContextParamSet; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +19,7 @@ public class MutableLootTable { private final ArrayList pools; private final ArrayList functions = new ArrayList<>(); - private final LootContextParamSet paramSet; + private final ContextKeySet paramSet; private final ResourceLocation randomSequence; public MutableLootTable(@NotNull LootTable table) {