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());