Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add registry context to LootTableLoadEvent #1677

Open
wants to merge 2 commits into
base: 1.21.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
--- a/net/minecraft/server/ReloadableServerRegistries.java
+++ b/net/minecraft/server/ReloadableServerRegistries.java
@@ -61,8 +_,16 @@
@@ -59,10 +_,19 @@
) {
return CompletableFuture.supplyAsync(
() -> {
+ var provider = net.neoforged.neoforge.common.CommonHooks.extractLookupProvider(p_336173_);
WritableRegistry<T> writableregistry = new MappedRegistry<>(p_335741_.registryKey(), Lifecycle.experimental());
Map<ResourceLocation, T> map = new HashMap<>();
+ Map<ResourceLocation, Optional<T>> optionalMap = new HashMap<>();
Expand All @@ -11,7 +14,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, provider);
+ if (value != null)
+ map.put(rl, value);
+ });
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/CommonHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
import net.minecraft.network.syncher.EntityDataSerializer;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
Expand Down Expand Up @@ -1524,6 +1525,18 @@ public static <T> RegistryLookup<T> resolveLookup(ResourceKey<? extends Registry
return null;
}

/**
* Extracts a {@link HolderLookup.Provider} from the given {@code ops}, if possible.
*
* @throws IllegalArgumentException if the ops were not created using a {@linkplain HolderLookup.Provider}
*/
public static HolderLookup.Provider extractLookupProvider(RegistryOps<?> ops) {
if (ops.lookupProvider instanceof RegistryOps.HolderLookupAdapter hla) {
return hla.lookupProvider;
}
throw new IllegalArgumentException("Registry ops has lookup provider " + ops.lookupProvider + " which is not a HolderLookupAdapter");
}

/**
* Creates a {@link UseOnContext} for {@link net.minecraft.core.dispenser.DispenseItemBehavior dispense behavior}.
*
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/net/neoforged/neoforge/event/EventHooks.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
29 changes: 27 additions & 2 deletions src/main/java/net/neoforged/neoforge/event/LootTableLoadEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -26,16 +31,36 @@
* only on the {@linkplain LogicalSide#SERVER logical server}.</p>
*/
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<LootTable> 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<LootTable> getKey() {
if (this.key == null) {
this.key = ResourceKey.create(Registries.LOOT_TABLE, name);
}
return this.key;
}

public LootTable getTable() {
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/META-INF/accesstransformer.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ public net.minecraft.gametest.framework.GameTestHelper testInfo # testInfo
public net.minecraft.gametest.framework.GameTestInfo sequences # sequences
public net.minecraft.gametest.framework.GameTestSequence <init>(Lnet/minecraft/gametest/framework/GameTestInfo;)V # <init>
protected net.minecraft.resources.RegistryOps <init>(Lcom/mojang/serialization/DynamicOps;Lnet/minecraft/resources/RegistryOps$RegistryInfoLookup;)V # constructor
public net.minecraft.resources.RegistryOps lookupProvider
public net.minecraft.resources.RegistryOps$HolderLookupAdapter
public net.minecraft.resources.RegistryOps$HolderLookupAdapter lookupProvider
public net.minecraft.resources.ResourceLocation validNamespaceChar(C)Z # validNamespaceChar
protected net.minecraft.server.MinecraftServer nextTickTimeNanos # nextTickTimeNanos
public net.minecraft.server.MinecraftServer$ReloadableResources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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());
Expand Down