Skip to content

Commit 17ebc64

Browse files
authored
Add registry context to LootTableLoadEvent (#1677)
1 parent 5a7d409 commit 17ebc64

File tree

6 files changed

+52
-8
lines changed

6 files changed

+52
-8
lines changed

patches/net/minecraft/server/ReloadableServerRegistries.java.patch

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
--- a/net/minecraft/server/ReloadableServerRegistries.java
22
+++ b/net/minecraft/server/ReloadableServerRegistries.java
3-
@@ -61,7 +_,15 @@
3+
@@ -61,7 +_,16 @@
44
() -> {
55
WritableRegistry<T> writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental());
66
Map<ResourceLocation, T> map = new HashMap<>();
77
- SimpleJsonResourceReloadListener.scanDirectory(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.codec(), map);
8+
+ var provider = net.neoforged.neoforge.common.CommonHooks.extractLookupProvider(p_336173_);
89
+ Map<ResourceLocation, Optional<T>> optionalMap = new HashMap<>();
910
+ SimpleJsonResourceReloadListener.scanDirectoryWithOptionalValues(p_335893_, p_335741_.registryKey(), p_336173_, p_335741_.conditionalCodec(), optionalMap);
1011
+ optionalMap.forEach((rl, optionalEntry) -> {
1112
+ optionalEntry.ifPresent(entry -> p_335741_.idSetter().accept(entry, rl));
1213
+ T value = optionalEntry.orElse(p_335741_.defaultValue());
13-
+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(rl, lootTable);
14+
+ if (value instanceof LootTable lootTable) value = (T) net.neoforged.neoforge.event.EventHooks.loadLootTable(provider, rl, lootTable);
1415
+ if (value != null)
1516
+ map.put(rl, value);
1617
+ });

src/main/java/net/neoforged/neoforge/common/CommonHooks.java

+13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
6666
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
6767
import net.minecraft.network.syncher.EntityDataSerializer;
68+
import net.minecraft.resources.RegistryOps;
6869
import net.minecraft.resources.ResourceKey;
6970
import net.minecraft.resources.ResourceLocation;
7071
import net.minecraft.server.MinecraftServer;
@@ -1524,6 +1525,18 @@ public static <T> RegistryLookup<T> resolveLookup(ResourceKey<? extends Registry
15241525
return null;
15251526
}
15261527

1528+
/**
1529+
* Extracts a {@link HolderLookup.Provider} from the given {@code ops}, if possible.
1530+
*
1531+
* @throws IllegalArgumentException if the ops were not created using a {@linkplain HolderLookup.Provider}
1532+
*/
1533+
public static HolderLookup.Provider extractLookupProvider(RegistryOps<?> ops) {
1534+
if (ops.lookupProvider instanceof RegistryOps.HolderLookupAdapter hla) {
1535+
return hla.lookupProvider;
1536+
}
1537+
throw new IllegalArgumentException("Registry ops has lookup provider " + ops.lookupProvider + " which is not a HolderLookupAdapter");
1538+
}
1539+
15271540
/**
15281541
* Creates a {@link UseOnContext} for {@link net.minecraft.core.dispenser.DispenseItemBehavior dispense behavior}.
15291542
*

src/main/java/net/neoforged/neoforge/event/EventHooks.java

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.minecraft.core.BlockPos;
2727
import net.minecraft.core.Direction;
2828
import net.minecraft.core.Holder;
29+
import net.minecraft.core.HolderLookup;
2930
import net.minecraft.core.HolderLookup.RegistryLookup;
3031
import net.minecraft.core.NonNullList;
3132
import net.minecraft.core.RegistryAccess;
@@ -688,10 +689,11 @@ public static boolean onProjectileImpact(Projectile projectile, HitResult ray) {
688689
* which maps to an empty {@link Optional} in {@link LootDataType#deserialize(ResourceLocation, DynamicOps, Object)}
689690
*/
690691
@Nullable
691-
public static LootTable loadLootTable(ResourceLocation name, LootTable table) {
692+
@ApiStatus.Internal
693+
public static LootTable loadLootTable(HolderLookup.Provider registries, ResourceLocation name, LootTable table) {
692694
if (table == LootTable.EMPTY) // Empty table has a null name, and shouldn't be modified anyway.
693695
return null;
694-
LootTableLoadEvent event = new LootTableLoadEvent(name, table);
696+
LootTableLoadEvent event = new LootTableLoadEvent(registries, name, table);
695697
if (NeoForge.EVENT_BUS.post(event).isCanceled() || event.getTable() == LootTable.EMPTY)
696698
return null;
697699
return event.getTable();

src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
package net.neoforged.neoforge.event;
77

88
import java.util.Objects;
9+
import net.minecraft.core.HolderLookup;
10+
import net.minecraft.core.registries.Registries;
11+
import net.minecraft.resources.ResourceKey;
912
import net.minecraft.resources.ResourceLocation;
1013
import net.minecraft.world.level.storage.loot.LootTable;
1114
import net.neoforged.bus.api.Event;
1215
import net.neoforged.bus.api.ICancellableEvent;
1316
import net.neoforged.fml.LogicalSide;
1417
import net.neoforged.neoforge.common.NeoForge;
18+
import org.jetbrains.annotations.ApiStatus;
19+
import org.jetbrains.annotations.Nullable;
1520

1621
/**
1722
* Fired when a {@link LootTable} is loaded from JSON.
@@ -26,18 +31,38 @@
2631
* only on the {@linkplain LogicalSide#SERVER logical server}.</p>
2732
*/
2833
public class LootTableLoadEvent extends Event implements ICancellableEvent {
34+
private final HolderLookup.Provider registries;
2935
private final ResourceLocation name;
3036
private LootTable table;
3137

32-
public LootTableLoadEvent(ResourceLocation name, LootTable table) {
38+
@Nullable
39+
private ResourceKey<LootTable> key;
40+
41+
@ApiStatus.Internal
42+
public LootTableLoadEvent(HolderLookup.Provider registries, ResourceLocation name, LootTable table) {
43+
this.registries = registries;
3344
this.name = name;
3445
this.table = table;
3546
}
3647

48+
/**
49+
* {@return a lookup provider that can be used to access registries}
50+
*/
51+
public HolderLookup.Provider getRegistries() {
52+
return this.registries;
53+
}
54+
3755
public ResourceLocation getName() {
3856
return this.name;
3957
}
4058

59+
public ResourceKey<LootTable> getKey() {
60+
if (this.key == null) {
61+
this.key = ResourceKey.create(Registries.LOOT_TABLE, name);
62+
}
63+
return this.key;
64+
}
65+
4166
public LootTable getTable() {
4267
return this.table;
4368
}

src/main/resources/META-INF/accesstransformer.cfg

+3
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ public net.minecraft.gametest.framework.GameTestHelper testInfo # testInfo
126126
public net.minecraft.gametest.framework.GameTestInfo sequences # sequences
127127
public net.minecraft.gametest.framework.GameTestSequence <init>(Lnet/minecraft/gametest/framework/GameTestInfo;)V # <init>
128128
protected net.minecraft.resources.RegistryOps <init>(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryOps$RegistryInfoLookup;)V # constructor
129+
public net.minecraft.resources.RegistryOps lookupProvider
130+
public net.minecraft.resources.RegistryOps$HolderLookupAdapter
131+
public net.minecraft.resources.RegistryOps$HolderLookupAdapter lookupProvider
129132
public net.minecraft.resources.ResourceLocation validNamespaceChar(C)Z # validNamespaceChar
130133
protected net.minecraft.server.MinecraftServer nextTickTimeNanos # nextTickTimeNanos
131134
public net.minecraft.server.MinecraftServer$ReloadableResources

tests/src/main/java/net/neoforged/neoforge/debug/loot/LootPoolTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ static void pinkConcreteLootTableCanceled(final DynamicTest test, final Registra
9292
event.getLookupProvider()));
9393

9494
NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> {
95-
if (event.getName().equals(lootTableToUse.location())) {
95+
if (event.getKey() == lootTableToUse) {
9696
event.setCanceled(true);
9797
}
9898
});
@@ -131,7 +131,7 @@ static void orangeConcreteLootTableReplaced(final DynamicTest test, final Regist
131131
event.getLookupProvider()));
132132

133133
NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> {
134-
if (event.getName().equals(lootTableToUse.location())) {
134+
if (event.getKey() == lootTableToUse) {
135135
LootPoolSingletonContainer.Builder<?> entry = LootItem.lootTableItem(Items.BLUE_CONCRETE);
136136
LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion());
137137
event.setTable(new LootTable.Builder().withPool(pool).build());
@@ -172,7 +172,7 @@ static void yellowConcreteLootTableAppended(final DynamicTest test, final Regist
172172
event.getLookupProvider()));
173173

174174
NeoForge.EVENT_BUS.addListener((final LootTableLoadEvent event) -> {
175-
if (event.getName().equals(lootTableToUse.location())) {
175+
if (event.getKey() == lootTableToUse) {
176176
LootPoolSingletonContainer.Builder<?> entry = LootItem.lootTableItem(Items.YELLOW_CONCRETE);
177177
LootPool.Builder pool = LootPool.lootPool().setRolls(ConstantValue.exactly(1)).add(entry).when(ExplosionCondition.survivesExplosion());
178178
event.getTable().addPool(pool.build());

0 commit comments

Comments
 (0)