loot cleanup wip!

This commit is contained in:
petrak@ 2023-01-22 21:59:48 -06:00
parent 18cab3e0e3
commit edc4012f69
7 changed files with 115 additions and 17 deletions

View file

@ -6,15 +6,17 @@ import org.jetbrains.annotations.Nullable;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
public enum ScrollQuantity {
NONE(null),
FEW(modLoc("inject/scroll_loot_few")),
SOME(modLoc("inject/scroll_loot_some")),
MANY(modLoc("inject/scroll_loot_many"));
NONE(null, 0),
FEW(modLoc("inject/scroll_loot_few"), 2),
SOME(modLoc("inject/scroll_loot_some"), 3),
MANY(modLoc("inject/scroll_loot_many"), 4);
private final ResourceLocation pool;
public final int countRange;
ScrollQuantity(ResourceLocation pool) {
ScrollQuantity(ResourceLocation pool, int countRange) {
this.pool = pool;
this.countRange = countRange;
}
@Nullable

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.common.loot;
import at.petrak.hexcasting.api.misc.ScrollQuantity;
import at.petrak.hexcasting.api.mod.HexConfig;
import net.minecraft.Util;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.storage.loot.LootPool;
@ -9,12 +10,40 @@ import net.minecraft.world.level.storage.loot.entries.LootPoolEntryContainer;
import net.minecraft.world.level.storage.loot.entries.LootTableReference;
import net.minecraft.world.level.storage.loot.providers.number.UniformGenerator;
import java.util.EnumMap;
import java.util.List;
import java.util.function.Consumer;
import static at.petrak.hexcasting.api.HexAPI.modLoc;
// https://github.com/VazkiiMods/Botania/blob/1.18.x/Xplat/src/main/java/vazkii/botania/common/loot/LootHandler.java
// We need to inject dungeon loot (scrolls and lore), make amethyst drop fewer shards, and the extra dust stuff.
// On forge we do it the "right" way with global loot modifiers; modifiable via a datapack.
// On fabric we do the addition of items by mixing in to loot loading and injecting some loot tables we only generate on
// Fabric as addons, and the subtraction with a loot function. so it's customizable for datapack devs.
public class HexLootHandler {
// TODO: remove ScrollQuantity, use this class as the source of truth for GLM gen on forge and inject/ loot tables
// on fabric
public static final EnumMap<ScrollQuantity, List<ResourceLocation>> DEFAULT_INJECTS = Util.make(() -> {
var map = new EnumMap<ScrollQuantity, List<ResourceLocation>>(ScrollQuantity.class);
map.put(ScrollQuantity.FEW, List.of(
new ResourceLocation("minecraft", "chests/jungle_temple"),
new ResourceLocation("minecraft", "chests/simple_dungeon"),
new ResourceLocation("minecraft", "chests/village/village_cartographer")));
map.put(ScrollQuantity.SOME, List.of(
new ResourceLocation("minecraft", "chests/bastion_treasure"),
new ResourceLocation("minecraft", "chests/pillager_outpost"),
new ResourceLocation("minecraft", "chests/shipwreck_map")
));
map.put(ScrollQuantity.MANY, List.of(
// ancient city chests have amethyst in them, thinking emoji
new ResourceLocation("minecraft", "chests/ancient_city"),
new ResourceLocation("minecraft", "chests/stronghold_library")));
return map;
});
public static final ResourceLocation FUNC_AMETHYST_SHARD_REDUCER = modLoc("amethyst_shard_reducer");
public static final ResourceLocation TABLE_INJECT_AMETHYST_CLUSTER = modLoc("inject/amethyst_cluster");

View file

@ -1,5 +1,6 @@
package at.petrak.hexcasting.datagen;
import at.petrak.hexcasting.api.misc.ScrollQuantity;
import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate;
import at.petrak.hexcasting.common.lib.HexBlocks;
import at.petrak.hexcasting.common.lib.HexItems;
@ -101,19 +102,19 @@ public class HexLootTables extends PaucalLootTableProvider {
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1)))
.when(noSilkTouchCond).when(goodAtAmethystingCond)
.when(BonusLevelTableCondition.bonusLevelFlatChance(Enchantments.BLOCK_FORTUNE,
0.25f, 0.35f, 0.5f, 0.75f, 1.0f));
0.25f, 0.35f, 0.5f, 0.75f, 1.0f));
var isThatAnMFingBadBrandonSandersonReference = LootPool.lootPool()
.add(LootItem.lootTableItem(HexItems.CHARGED_AMETHYST))
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1)))
.when(noSilkTouchCond).when(goodAtAmethystingCond.invert())
.when(LootItemRandomChanceCondition.randomChance(0.125f));
.add(LootItem.lootTableItem(HexItems.CHARGED_AMETHYST))
.apply(SetItemCountFunction.setCount(ConstantValue.exactly(1)))
.when(noSilkTouchCond).when(goodAtAmethystingCond.invert())
.when(LootItemRandomChanceCondition.randomChance(0.125f));
lootTables.put(HexLootHandler.TABLE_INJECT_AMETHYST_CLUSTER, LootTable.lootTable()
.withPool(dustPoolWhenGood)
.withPool(dustPoolWhenBad)
.withPool(isThatAnMFingBrandonSandersonReference)
.withPool(isThatAnMFingBadBrandonSandersonReference));
.withPool(dustPoolWhenGood)
.withPool(dustPoolWhenBad)
.withPool(isThatAnMFingBrandonSandersonReference)
.withPool(isThatAnMFingBadBrandonSandersonReference));
String[] rarities = new String[]{
"few",
@ -121,7 +122,8 @@ public class HexLootTables extends PaucalLootTableProvider {
"many"
};
for (int i = 0; i < rarities.length; i++) {
var scrollPool = makeScrollAdder(i + 1);
var quantity = ScrollQuantity.values()[i + 1];
var scrollPool = makeScrollAdder(quantity.countRange);
lootTables.put(modLoc("inject/scroll_loot_" + rarities[i]), scrollPool);
}
}

View file

@ -26,6 +26,8 @@ import at.petrak.hexcasting.forge.cap.ForgeCapabilityHandler;
import at.petrak.hexcasting.forge.datagen.HexForgeDataGenerators;
import at.petrak.hexcasting.forge.interop.curios.CuriosApiInterop;
import at.petrak.hexcasting.forge.interop.curios.CuriosRenderers;
import at.petrak.hexcasting.forge.lib.ForgeHexArgumentTypeRegistry;
import at.petrak.hexcasting.forge.lib.ForgeHexLootMods;
import at.petrak.hexcasting.forge.network.ForgePacketHandler;
import at.petrak.hexcasting.forge.network.MsgBrainsweepAck;
import at.petrak.hexcasting.forge.recipe.ForgeModConditionalIngredient;
@ -111,6 +113,7 @@ public class ForgeHexInitializer {
bind(IXplatAbstractions.INSTANCE.getEvalSoundRegistry().key(), HexEvalSounds::register);
ForgeHexArgumentTypeRegistry.ARGUMENT_TYPES.register(getModEventBus());
ForgeHexLootMods.REGISTRY.register(getModEventBus());
HexAdvancementTriggers.registerTriggers();
}

View file

@ -1,4 +1,4 @@
package at.petrak.hexcasting.forge;
package at.petrak.hexcasting.forge.lib;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.common.command.PatternResLocArgument;
@ -16,7 +16,8 @@ public class ForgeHexArgumentTypeRegistry {
ForgeRegistries.COMMAND_ARGUMENT_TYPES, HexAPI.MOD_ID);
// how fucking ergonomic
public static final RegistryObject<ArgumentTypeInfo<PatternResLocArgument, SingletonArgumentInfo<PatternResLocArgument>.Template>>
public static final RegistryObject<ArgumentTypeInfo<PatternResLocArgument,
SingletonArgumentInfo<PatternResLocArgument>.Template>>
PATTERN_RESLOC = register(PatternResLocArgument.class,
"pattern",
SingletonArgumentInfo.contextFree(PatternResLocArgument::id)

View file

@ -0,0 +1,17 @@
package at.petrak.hexcasting.forge.lib;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod;
import com.mojang.serialization.Codec;
import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.registries.DeferredRegister;
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.RegistryObject;
public class ForgeHexLootMods {
public static final DeferredRegister<Codec<? extends IGlobalLootModifier>> REGISTRY = DeferredRegister.create(
ForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, HexAPI.MOD_ID);
public static final RegistryObject<Codec<ForgeHexScrollLootMod>> INJECT_SCROLLS = REGISTRY.register(
"inject_scrolls", ForgeHexScrollLootMod.CODEC);
}

View file

@ -0,0 +1,44 @@
package at.petrak.hexcasting.forge.loot;
import at.petrak.hexcasting.api.misc.ScrollQuantity;
import com.google.common.base.Suppliers;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
import net.minecraftforge.common.loot.IGlobalLootModifier;
import net.minecraftforge.common.loot.LootModifier;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
public class ForgeHexScrollLootMod extends LootModifier {
public static final Supplier<Codec<ForgeHexScrollLootMod>> CODEC =
Suppliers.memoize(() -> RecordCodecBuilder.create(
inst -> codecStart(inst).and(
Codec.INT.fieldOf("quantity").forGetter(it -> it.quantity.ordinal())
).apply(inst, (cond, quant) -> new ForgeHexScrollLootMod(cond, ScrollQuantity.values()[quant]))
));
public final ScrollQuantity quantity;
public ForgeHexScrollLootMod(LootItemCondition[] conditionsIn, ScrollQuantity quantity) {
super(conditionsIn);
this.quantity = quantity;
}
@Override
protected @NotNull ObjectArrayList<ItemStack> doApply(ObjectArrayList<ItemStack> generatedLoot,
LootContext context) {
var injectedTable = context.getLootTable(this.quantity.getPool());
injectedTable.getRandomItemsRaw(context, generatedLoot::add);
return generatedLoot;
}
@Override
public Codec<? extends IGlobalLootModifier> codec() {
return null;
}
}