yatta! close #377 and make lore spawn lmao

This commit is contained in:
petrak@ 2023-01-23 14:31:19 -06:00
parent aca2c19be6
commit abc2e7862b
24 changed files with 245 additions and 18 deletions

View file

@ -88,6 +88,10 @@ public class HexConfig {
return keys.stream().map(ResourceLocation::new).noneMatch(key::equals);
}
public static boolean anyMatchResLoc(List<? extends ResourceLocation> keys, ResourceLocation key) {
return keys.stream().anyMatch(key::equals);
}
// oh man this is aesthetically pleasing
private static CommonConfigAccess common = null;
private static ClientConfigAccess client = null;

View file

@ -9,11 +9,11 @@ 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:
// - Scrolls are done with a loot mod
// - Scrolls and lore are done with a loot mod
// - Amethyst drop fiddling is done with another loot mod; the shard delta is in the loot mod data and the rest of
// the stuff is loaded from TABLE_INJECT_AMETHYST_CLUSTER
// On fabric:
// - Scrolls are done with a lootLoad listener and the amounts are loaded from config
// - Scrolls and lore are done with a lootLoad listener and the amounts are loaded from config
// - Amethyst shard reduction is done with a loot function mixed in to always be on amethyst clusters, god, cause I
// don't think it's facile to use the loot pool api to try to figure out which pool is for the amethyst and reduce it
// - Amethyst dust and crystals are done by adding the loot table Forge uses in directly via listener
@ -47,11 +47,26 @@ public class HexLootHandler {
new ScrollInjection(new ResourceLocation("minecraft", "chests/stronghold_library"), 5)
);
public static final ImmutableList<ResourceLocation> DEFAULT_LORE_INJECTS = ImmutableList.of(
new ResourceLocation("minecraft", "chests/simple_dungeon"),
new ResourceLocation("minecraft", "chests/abandoned_mineshaft"),
new ResourceLocation("minecraft", "chests/pillager_outpost"),
new ResourceLocation("minecraft", "chests/woodland_mansion"),
new ResourceLocation("minecraft", "chests/stronghold_library"),
// >:)
new ResourceLocation("minecraft", "chests/village/village_desert_house"),
new ResourceLocation("minecraft", "chests/village/village_plains_house"),
new ResourceLocation("minecraft", "chests/village/village_savanna_house"),
new ResourceLocation("minecraft", "chests/village/village_snowy_house"),
new ResourceLocation("minecraft", "chests/village/village_taiga_house")
);
public static int getScrollCount(int range, RandomSource random) {
return Math.max(random.nextIntBetweenInclusive(-range, range), 0);
}
public static final double DEFAULT_SHARD_MODIFICATION = -0.5;
public static final double DEFAULT_LORE_CHANCE = 0.4;
public static final ResourceLocation TABLE_INJECT_AMETHYST_CLUSTER = modLoc("inject/amethyst_cluster");

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-01-22T23:57:23.050599591 Tags for minecraft:item
// 1.19.2 2023-01-23T14:22:44.2568588 Tags for minecraft:item
5928bad07d3872bb60f29ef4f3c885c8e1967c20 data/hexcasting/tags/items/phial_base.json
fdb48f194d7937ab6b423fa4b90a4d438bf6dd90 data/minecraft/tags/items/wooden_doors.json
e5df19a1dc6eadf14cd9b0f0fe45a74330b745e9 data/hexcasting/tags/items/edified_planks.json

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-01-22T23:57:23.070700759 LootTables
// 1.19.2 2023-01-23T14:22:44.219077975 LootTables
dec1d3592e82f99d9e059d9c771530f103b2bda5 data/hexcasting/loot_tables/blocks/empty_directrix.json
2c42fc5d8c74c98ad15b8bd50f56541fccbef750 data/hexcasting/loot_tables/blocks/edified_tile.json
cfb39e2151725fe4f9a7269d9b5de8031ea54a44 data/hexcasting/loot_tables/blocks/directrix_redstone.json

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-01-22T23:57:23.071366626 Tags for minecraft:block
// 1.19.2 2023-01-23T14:22:44.257772029 Tags for minecraft:block
20183cd61968ff6548df2dde1100b6378d68d64b data/minecraft/tags/blocks/wooden_buttons.json
357eddf3cee6f16725bed0701d57b2ca3097d74d data/minecraft/tags/blocks/mineable/shovel.json
5216ba5c57db29b8dee9aebc63a2e3b17c97dc17 data/minecraft/tags/blocks/wooden_trapdoors.json

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-01-22T23:57:23.069878587 Tags for hexcasting:action
// 1.19.2 2023-01-23T14:22:44.223016397 Tags for hexcasting:action
e5afc567ea17f035e4eb1d1d48825100b7f6ad68 data/hexcasting/tags/action/per_world_pattern.json
e5afc567ea17f035e4eb1d1d48825100b7f6ad68 data/hexcasting/tags/action/requires_enlightenment.json
e5afc567ea17f035e4eb1d1d48825100b7f6ad68 data/hexcasting/tags/action/can_start_enlighten.json

View file

@ -1,4 +1,4 @@
// 1.19.2 2023-01-22T23:57:23.052460583 Recipes
// 1.19.2 2023-01-23T14:22:44.22380957 Recipes
9f75d3e93ecbbbf3ed9a92b2943397e09dcae1a9 data/hexcasting/recipes/dye_colorizer_light_blue.json
04569ccadfd99f203b0485d0c3e877209290f2b3 data/hexcasting/advancements/recipes/hexcasting.creative_tab/dye_colorizer_pink.json
2a9d4a0f3618abf9e9b8699b318a984d2c836913 data/hexcasting/advancements/recipes/brainsweep/brainsweep/directrix_redstone.json

View file

@ -19,6 +19,7 @@ import net.minecraft.world.level.Level;
import java.util.List;
import static at.petrak.hexcasting.api.mod.HexConfig.anyMatchResLoc;
import static at.petrak.hexcasting.api.mod.HexConfig.noneMatch;
@Config(name = HexAPI.MOD_ID)
@ -156,6 +157,13 @@ public class FabricHexConfig extends PartitioningSerializer.GlobalData {
@ConfigEntry.Gui.Excluded
private transient Object2IntMap<ResourceLocation> scrollInjections;
// TODO: hook this up to the config, change Jankery, test, also test scroll injects on fabric
@ConfigEntry.Gui.Tooltip
private List<ResourceLocation> loreInjections = HexLootHandler.DEFAULT_LORE_INJECTS;
@ConfigEntry.Gui.Tooltip
private double loreChance = HexLootHandler.DEFAULT_LORE_CHANCE;
@Override
public void validatePostLoad() throws ValidationException {
this.maxRecurseDepth = Math.max(this.maxRecurseDepth, 0);
@ -165,6 +173,8 @@ public class FabricHexConfig extends PartitioningSerializer.GlobalData {
for (var mirror : this.scrollInjectionsRaw) {
this.scrollInjections.put(mirror.injectee(), mirror.countRange());
}
this.loreChance = Mth.clamp(this.loreChance, 0.0, 1.0);
}
@Override
@ -209,6 +219,14 @@ public class FabricHexConfig extends PartitioningSerializer.GlobalData {
return this.scrollInjections.getOrDefault(lootTable, -1);
}
public boolean shouldInjectLore(ResourceLocation lootTable) {
return anyMatchResLoc(this.loreInjections, lootTable);
}
public double getLoreChance() {
return loreChance;
}
record ScrollInjectionMirror(ResourceLocation injectee, int countRange) {
}
}

View file

@ -9,6 +9,8 @@ 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.LootTableReference;
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition;
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 org.jetbrains.annotations.NotNull;
@ -23,11 +25,15 @@ public class FabricHexLootModJankery {
public static void lootLoad(ResourceLocation id, Consumer<LootPool.Builder> addPool) {
if (id.equals(Blocks.AMETHYST_CLUSTER.getLootTable())) {
addPool.accept(makeAmethystInjectPool());
} else {
int countRange = FabricHexInitializer.CONFIG.server.scrollRangeForLootTable(id);
if (countRange != -1) {
addPool.accept(makeScrollAddPool(countRange));
}
}
int countRange = FabricHexInitializer.CONFIG.server.scrollRangeForLootTable(id);
if (countRange != -1) {
addPool.accept(makeScrollAddPool(countRange));
}
if (FabricHexInitializer.CONFIG.server.shouldInjectLore(id)) {
addPool.accept(makeLoreAddPool(FabricHexInitializer.CONFIG.server.getLoreChance()));
}
}
@ -43,4 +49,11 @@ public class FabricHexLootModJankery {
.add(LootItem.lootTableItem(HexItems.SCROLL_LARGE))
.apply(() -> new AddPerWorldPatternToScrollFunc(new LootItemCondition[0]));
}
private static LootPool.Builder makeLoreAddPool(double chance) {
return LootPool.lootPool()
.when(LootItemRandomChanceCondition.randomChance((float) chance))
.setRolls(ConstantValue.exactly(1))
.add(LootItem.lootTableItem(HexItems.LORE_FRAGMENT));
}
}

View file

@ -1,6 +1,16 @@
// 1.19.2 2023-01-22T23:58:04.861380072 Global Loot Modifiers : hexcasting
bdfa7329fd17b9128e2bc03c662682e434d74c29 data/forge/loot_modifiers/global_loot_modifiers.json
// 1.19.2 2023-01-23T14:20:40.916977642 Global Loot Modifiers : hexcasting
fcf77123631746f3ee4e815183c0731c3ec206c9 data/forge/loot_modifiers/global_loot_modifiers.json
28ca895a27221312c2451f26646111a68aadbf6c data/hexcasting/loot_modifiers/amethyst_cluster.json
f98707c91dc8712409833df1e5da245e9b14ebfa data/hexcasting/loot_modifiers/lore/minecraft/chests/abandoned_mineshaft.json
16b4bbb5358f2fcad31a8b796cdc3eef28caaf09 data/hexcasting/loot_modifiers/lore/minecraft/chests/pillager_outpost.json
6d6a9fd35a8f4e94c7ae64bf8c130b40d0d7d0e4 data/hexcasting/loot_modifiers/lore/minecraft/chests/simple_dungeon.json
d1b282c57a8f5d1a37f3b87fbdba408b2a1b1415 data/hexcasting/loot_modifiers/lore/minecraft/chests/stronghold_library.json
85e98d5aafc8f80415acf2a7e88acc09b6e17e45 data/hexcasting/loot_modifiers/lore/minecraft/chests/village/village_desert_house.json
4f23231622d1aa9d69511af2a783838f851888c4 data/hexcasting/loot_modifiers/lore/minecraft/chests/village/village_plains_house.json
1cf8de77951e07da409c5b11016f8ec513910723 data/hexcasting/loot_modifiers/lore/minecraft/chests/village/village_savanna_house.json
e52b9cba9d685a2ca7ea7db629c7c0990f12be26 data/hexcasting/loot_modifiers/lore/minecraft/chests/village/village_snowy_house.json
a59a9c55b02b76c0e3f6a2ee4fa7bcf3ab538595 data/hexcasting/loot_modifiers/lore/minecraft/chests/village/village_taiga_house.json
348688be7af2a3ea62c605428c958e62e449252d data/hexcasting/loot_modifiers/lore/minecraft/chests/woodland_mansion.json
a89a9e3113b83c6eb978f101aad42a6b37e7c1d8 data/hexcasting/loot_modifiers/scroll/minecraft/chests/abandoned_mineshaft.json
bfac0ff9e84cd974ccfb47edc9dce78476470103 data/hexcasting/loot_modifiers/scroll/minecraft/chests/ancient_city.json
0fcb299789a1b0162ab81a025a06b1aab5eb504b data/hexcasting/loot_modifiers/scroll/minecraft/chests/bastion_other.json

View file

@ -1,18 +1,28 @@
{
"entries": [
"hexcasting:scroll/minecraft/chests/bastion_other",
"hexcasting:scroll/minecraft/chests/nether_bridge",
"hexcasting:scroll/minecraft/chests/village/village_cartographer",
"hexcasting:lore/minecraft/chests/village/village_taiga_house",
"hexcasting:scroll/minecraft/chests/shipwreck_map",
"hexcasting:lore/minecraft/chests/village/village_snowy_house",
"hexcasting:scroll/minecraft/chests/abandoned_mineshaft",
"hexcasting:amethyst_cluster",
"hexcasting:lore/minecraft/chests/village/village_plains_house",
"hexcasting:lore/minecraft/chests/stronghold_library",
"hexcasting:scroll/minecraft/chests/bastion_other",
"hexcasting:lore/minecraft/chests/woodland_mansion",
"hexcasting:lore/minecraft/chests/village/village_desert_house",
"hexcasting:scroll/minecraft/chests/end_city_treasure",
"hexcasting:scroll/minecraft/chests/jungle_temple",
"hexcasting:scroll/minecraft/chests/bastion_treasure",
"hexcasting:lore/minecraft/chests/village/village_savanna_house",
"hexcasting:scroll/minecraft/chests/pillager_outpost",
"hexcasting:scroll/minecraft/chests/desert_pyramid",
"hexcasting:scroll/minecraft/chests/shipwreck_map",
"hexcasting:scroll/minecraft/chests/abandoned_mineshaft",
"hexcasting:amethyst_cluster",
"hexcasting:lore/minecraft/chests/abandoned_mineshaft",
"hexcasting:lore/minecraft/chests/pillager_outpost",
"hexcasting:scroll/minecraft/chests/ancient_city",
"hexcasting:scroll/minecraft/chests/stronghold_library",
"hexcasting:lore/minecraft/chests/simple_dungeon",
"hexcasting:scroll/minecraft/chests/woodland_mansion",
"hexcasting:scroll/minecraft/chests/simple_dungeon"
],

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/abandoned_mineshaft"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/pillager_outpost"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/simple_dungeon"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/stronghold_library"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/village/village_desert_house"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/village/village_plains_house"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/village/village_savanna_house"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/village/village_snowy_house"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/village/village_taiga_house"
}
]
}

View file

@ -0,0 +1,10 @@
{
"type": "hexcasting:inject_lore",
"chance": 0.4,
"conditions": [
{
"condition": "forge:loot_table_id",
"loot_table_id": "minecraft:chests/woodland_mansion"
}
]
}

View file

@ -3,6 +3,7 @@ package at.petrak.hexcasting.forge.datagen;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.common.loot.HexLootHandler;
import at.petrak.hexcasting.forge.loot.ForgeHexAmethystLootMod;
import at.petrak.hexcasting.forge.loot.ForgeHexLoreLootMod;
import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod;
import net.minecraft.data.DataGenerator;
import net.minecraft.world.level.block.Blocks;
@ -24,8 +25,16 @@ public class ForgeHexLootModGen extends GlobalLootModifierProvider {
}, injection.countRange()));
}
for (var injection : HexLootHandler.DEFAULT_LORE_INJECTS) {
var name = "lore/%s/%s".formatted(injection.getNamespace(), injection.getPath());
add(name, new ForgeHexLoreLootMod(new LootItemCondition[]{
LootTableIdCondition.builder(injection).build(),
}, HexLootHandler.DEFAULT_LORE_CHANCE));
}
add("amethyst_cluster", new ForgeHexAmethystLootMod(new LootItemCondition[]{
LootTableIdCondition.builder(Blocks.AMETHYST_CLUSTER.getLootTable()).build()
}, HexLootHandler.DEFAULT_SHARD_MODIFICATION));
}
}

View file

@ -2,6 +2,7 @@ package at.petrak.hexcasting.forge.lib;
import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.forge.loot.ForgeHexAmethystLootMod;
import at.petrak.hexcasting.forge.loot.ForgeHexLoreLootMod;
import at.petrak.hexcasting.forge.loot.ForgeHexScrollLootMod;
import com.mojang.serialization.Codec;
import net.minecraftforge.common.loot.IGlobalLootModifier;
@ -15,6 +16,8 @@ public class ForgeHexLootMods {
public static final RegistryObject<Codec<ForgeHexScrollLootMod>> INJECT_SCROLLS = REGISTRY.register(
"inject_scrolls", ForgeHexScrollLootMod.CODEC);
public static final RegistryObject<Codec<ForgeHexLoreLootMod>> INJECT_LORE = REGISTRY.register(
"inject_lore", ForgeHexLoreLootMod.CODEC);
public static final RegistryObject<Codec<ForgeHexAmethystLootMod>> AMETHYST = REGISTRY.register(
"amethyst_cluster", ForgeHexAmethystLootMod.CODEC);
}

View file

@ -0,0 +1,45 @@
package at.petrak.hexcasting.forge.loot;
import at.petrak.hexcasting.common.lib.HexItems;
import at.petrak.hexcasting.forge.lib.ForgeHexLootMods;
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.LootModifier;
import org.jetbrains.annotations.NotNull;
import java.util.function.Supplier;
public class ForgeHexLoreLootMod extends LootModifier {
public static final Supplier<Codec<ForgeHexLoreLootMod>> CODEC =
Suppliers.memoize(() -> RecordCodecBuilder.create(
inst -> codecStart(inst).and(
Codec.DOUBLE.fieldOf("chance").forGetter(it -> it.chance)
).apply(inst, ForgeHexLoreLootMod::new)
));
public final double chance;
public ForgeHexLoreLootMod(LootItemCondition[] conditionsIn, double chance) {
super(conditionsIn);
this.chance = chance;
}
@Override
protected @NotNull ObjectArrayList<ItemStack> doApply(ObjectArrayList<ItemStack> generatedLoot,
LootContext context) {
if (context.getRandom().nextDouble() < this.chance) {
generatedLoot.add(new ItemStack(HexItems.LORE_FRAGMENT));
}
return generatedLoot;
}
@Override
public Codec<ForgeHexLoreLootMod> codec() {
return ForgeHexLootMods.INJECT_LORE.get();
}
}