From ffca39bcca649dbd652e70a0b5d2e9ef3021f168 Mon Sep 17 00:00:00 2001 From: Matyrobbrt Date: Sat, 9 Nov 2024 14:35:44 +0200 Subject: [PATCH] Add registry context to `LootTableLoadEvent` See #1625 --- .../ReloadableServerRegistries.java.patch | 2 +- .../neoforged/neoforge/event/EventHooks.java | 6 ++-- .../neoforge/event/LootTableLoadEvent.java | 29 +++++++++++++++++-- .../resources/META-INF/accesstransformer.cfg | 1 + .../neoforge/debug/loot/LootPoolTest.java | 6 ++-- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch index ff31d3b5cf..fd59dfd417 100644 --- a/patches/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/patches/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -11,7 +11,7 @@ + optionalMap.forEach((rl, optionalEntry) -> { + optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl)); + T value = optionalEntry.orElse(p_335741_.defaultValue()); -+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable); ++ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable, (HolderLookup.Provider) p_336173_.lookupProvider); + if (value != null) + map.put(rl, value); + }); diff --git a/src/main/java/net/neoforged/neoforge/event/EventHooks.java b/src/main/java/net/neoforged/neoforge/event/EventHooks.java index c5109000f3..1c71958c91 100644 --- a/src/main/java/net/neoforged/neoforge/event/EventHooks.java +++ b/src/main/java/net/neoforged/neoforge/event/EventHooks.java @@ -26,6 +26,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.NonNullList; import net.minecraft.core.RegistryAccess; @@ -688,10 +689,11 @@ public static boolean onProjectileImpact(Projectile projectile, HitResult ray) { * which maps to an empty {@link Optional} in {@link LootDataType#deserialize(ResourceLocation, DynamicOps, Object)} */ @Nullable - public static LootTable loadLootTable(ResourceLocation name, LootTable table) { + @ApiStatus.Internal + public static LootTable loadLootTable(ResourceLocation name, LootTable table, HolderLookup.Provider registries) { if (table == LootTable.EMPTY) // Empty table has a null name, and shouldn't be modified anyway. return null; - LootTableLoadEvent event = new LootTableLoadEvent(name, table); + LootTableLoadEvent event = new LootTableLoadEvent(registries, name, table); if (NeoForge.EVENT_BUS.post(event).isCanceled() || event.getTable() == LootTable.EMPTY) return null; return event.getTable(); diff --git a/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java b/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java index 6c1cff856a..e09f4b9d0c 100644 --- a/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java +++ b/src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java @@ -6,12 +6,17 @@ package net.neoforged.neoforge.event; import java.util.Objects; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.storage.loot.LootTable; import net.neoforged.bus.api.Event; import net.neoforged.bus.api.ICancellableEvent; import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.common.NeoForge; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; /** * Fired when a {@link LootTable} is loaded from JSON. @@ -26,16 +31,36 @@ * only on the {@linkplain LogicalSide#SERVER logical server}.

*/ public class LootTableLoadEvent extends Event implements ICancellableEvent { + private final HolderLookup.Provider registries; private final ResourceLocation name; private LootTable table; - public LootTableLoadEvent(ResourceLocation name, LootTable table) { + @Nullable + private ResourceKey key; + + @ApiStatus.Internal + public LootTableLoadEvent(HolderLookup.Provider registries, ResourceLocation name, LootTable table) { + this.registries = registries; this.name = name; this.table = table; } + /** + * {@return a lookup provider that can be used to access registries} + */ + public HolderLookup.Provider getRegistries() { + return registries; + } + public ResourceLocation getName() { - return this.name; + return name; + } + + public ResourceKey getKey() { + if (this.key == null) { + this.key = ResourceKey.create(Registries.LOOT_TABLE, name); + } + return this.key; } public LootTable getTable() { diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index a9634170b7..67400f327c 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -158,6 +158,7 @@ public net.minecraft.gametest.framework.GameTestHelper testInfo # testInfo public net.minecraft.gametest.framework.GameTestInfo sequences # sequences public net.minecraft.gametest.framework.GameTestSequence (Lnet/minecraft/gametest/framework/GameTestInfo;)V # protected net.minecraft.resources.RegistryOps (Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryOps$RegistryInfoLookup;)V # constructor +public net.minecraft.resources.RegistryOps lookupProvider public net.minecraft.resources.ResourceLocation validNamespaceChar(C)Z # validNamespaceChar protected net.minecraft.server.MinecraftServer nextTickTimeNanos # nextTickTimeNanos public net.minecraft.server.MinecraftServer$ReloadableResources diff --git a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java index fce7b70d4a..10773f8c91 100644 --- a/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java +++ b/tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java @@ -92,7 +92,7 @@ static void pinkConcreteLootTableCanceled(final DynamicTest test, final Registra event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { event.setCanceled(true); } }); @@ -131,7 +131,7 @@ static void orangeConcreteLootTableReplaced(final DynamicTest test, final Regist event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { LootPoolSingletonContainer.Builder entry = LootItem.lootTableItem(Items.BLUE_CONCRETE); LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion()); event.setTable(new LootTable.Builder().withPool(pool).build()); @@ -172,7 +172,7 @@ static void yellowConcreteLootTableAppended(final DynamicTest test, final Regist event.getLookupProvider())); NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> { - if (event.getName().equals(lootTableToUse.location())) { + if (event.getKey() == lootTableToUse) { LootPoolSingletonContainer.Builder entry = LootItem.lootTableItem(Items.YELLOW_CONCRETE); LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion()); event.getTable().addPool(pool.build());