Skip to content
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
Expand Up @@ -17,6 +17,7 @@
package net.fabricmc.fabric.api.item.v1;

import net.minecraft.core.Holder;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;
Expand Down Expand Up @@ -76,7 +77,10 @@ private EnchantmentEvents() { }
*
* <p>Note: If you wish to modify the exclusive set of the enchantment, consider extending the
* {@linkplain net.minecraft.tags.EnchantmentTags relevant tag} through your mod's data pack instead.
*
* @deprecated Use {@link #MODIFY_WITH_LOOKUP} instead, which provides registry access via {@link RegistryOps.RegistryInfoLookup}
*/
@Deprecated
public static final Event<Modify> MODIFY = EventFactory.createArrayBacked(
Modify.class,
callbacks -> (key, builder, source) -> {
Expand All @@ -86,6 +90,29 @@ private EnchantmentEvents() { }
}
);

/**
* An event that allows an {@link Enchantment} to be modified without needing to fully override an enchantment.
*
* <p>This should only be used to modify the behavior of <em>external</em> enchantments, where 'external' means
* either vanilla or from another mod. For instance, a mod might add a bleed effect to Sharpness (and only Sharpness).
* For your own enchantments, you should simply define them in your mod's data pack. See the
* <a href="https://minecraft.wiki/w/Enchantment_definition">Enchantment Definition page</a> on the Minecraft Wiki
* for more information.
*
* <p>Note: If you wish to modify the exclusive set of the enchantment, consider extending the
* {@linkplain net.minecraft.tags.EnchantmentTags relevant tag} through your mod's data pack instead.
*
* <p>This is the preferred replacement for {@link #MODIFY}, providing access to registry information via {@link RegistryOps.RegistryInfoLookup}.
*/
public static final Event<ModifyWithLookup> MODIFY_WITH_LOOKUP = EventFactory.createArrayBacked(
ModifyWithLookup.class,
callbacks -> (key, builder, source, registries) -> {
for (ModifyWithLookup callback : callbacks) {
callback.modify(key, builder, source, registries);
}
}
);

@FunctionalInterface
public interface AllowEnchanting {
/**
Expand All @@ -106,6 +133,7 @@ TriState allowEnchanting(
}

@FunctionalInterface
@Deprecated
public interface Modify {
/**
* Modifies the effects of an {@link Enchantment}.
Expand All @@ -120,4 +148,22 @@ void modify(
EnchantmentSource source
);
}

@FunctionalInterface
public interface ModifyWithLookup {
/**
* Modifies the effects of an {@link Enchantment}.
*
* @param key The ID of the enchantment
* @param builder The enchantment builder
* @param source The source of the enchantment
* @param registryInfoLookup Lookup interface used to access registry information
*/
void modify(
Comment thread
Maganoos marked this conversation as resolved.
ResourceKey<Enchantment> key,
Enchantment.Builder builder,
EnchantmentSource source,
RegistryOps.RegistryInfoLookup registryInfoLookup
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.slf4j.LoggerFactory;

import net.minecraft.core.component.DataComponentType;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.packs.repository.PackSource;
import net.minecraft.server.packs.resources.Resource;
Expand All @@ -37,9 +38,9 @@
public class EnchantmentUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(EnchantmentUtil.class);

@SuppressWarnings("unchecked")
@SuppressWarnings({"unchecked", "deprecation"})
@Nullable
public static Enchantment modify(ResourceKey<Enchantment> key, Enchantment originalEnchantment, EnchantmentSource source) {
public static Enchantment modify(ResourceKey<Enchantment> key, Enchantment originalEnchantment, EnchantmentSource source, RegistryOps.RegistryInfoLookup registryInfoLookup) {
Enchantment.Builder builder = Enchantment.enchantment(originalEnchantment.definition());
EnchantmentBuilderAccessor accessor = (EnchantmentBuilderAccessor) builder;
BuilderExtensions builderExtensions = (BuilderExtensions) builder;
Expand All @@ -60,6 +61,7 @@ public static Enchantment modify(ResourceKey<Enchantment> key, Enchantment origi
builderExtensions.fabric$resetModified();

EnchantmentEvents.MODIFY.invoker().modify(key, builder, source);
EnchantmentEvents.MODIFY_WITH_LOOKUP.invoker().modify(key, builder, source, registryInfoLookup);
Comment thread
Maganoos marked this conversation as resolved.

if (builderExtensions.fabric$didModify()) {
LOGGER.debug("Enchantment {} was modified", key.identifier());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,22 @@
package net.fabricmc.fabric.mixin.item;

import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.llamalad7.mixinextras.sugar.Local;
import com.mojang.datafixers.util.Either;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import net.minecraft.core.RegistrationInfo;
import net.minecraft.resources.RegistryLoadTask;
import net.minecraft.resources.RegistryOps;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceManagerRegistryLoadTask;
import net.minecraft.server.packs.resources.Resource;
Expand All @@ -36,11 +42,14 @@

@Mixin(ResourceManagerRegistryLoadTask.class)
public class ResourceManagerRegistryLoadTaskMixin {
@Unique
private RegistryOps.RegistryInfoLookup registryInfoLookup;

@WrapOperation(method = "lambda$load$2", at = @At(value = "NEW", target = "net/minecraft/resources/RegistryLoadTask$PendingRegistration"))
private <T> RegistryLoadTask.PendingRegistration<?> modify(ResourceKey<T> key, Either<T, Exception> value, RegistrationInfo registrationInfo, Operation<RegistryLoadTask.PendingRegistration<T>> original, @Local(argsOnly = true) Resource resource) {
if (value.left().isPresent()) {
if (value.left().get() instanceof Enchantment enchantment) {
Enchantment modified = EnchantmentUtil.modify((ResourceKey<Enchantment>) key, enchantment, EnchantmentUtil.determineSource(resource));
Enchantment modified = EnchantmentUtil.modify((ResourceKey<Enchantment>) key, enchantment, EnchantmentUtil.determineSource(resource), registryInfoLookup);

if (modified != null) {
// Clear the knownPackInfo to force the server to sync the data pack to the client
Expand All @@ -52,4 +61,9 @@ private <T> RegistryLoadTask.PendingRegistration<?> modify(ResourceKey<T> key, E

return original.call(key, value, registrationInfo);
}

@Inject(method = "load", at = @At("HEAD"))
private void captureRegistries(RegistryOps.RegistryInfoLookup context, Executor executor, CallbackInfoReturnable<CompletableFuture<?>> cir) {
this.registryInfoLookup = context;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.EnchantmentTags;
import net.minecraft.world.entity.EntityTypes;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentEffectComponents;
Expand All @@ -46,8 +47,8 @@ public class CustomEnchantmentEffectsTest implements ModInitializer {

@Override
public void onInitialize() {
EnchantmentEvents.MODIFY.register(
(key, builder, source) -> {
EnchantmentEvents.MODIFY_WITH_LOOKUP.register(
(key, builder, source, registries) -> {
if (source.isBuiltin() && key == WEIRD_IMPALING) {
// make impaling set things on fire
builder.withEffect(
Expand All @@ -70,6 +71,9 @@ public void onInitialize() {
.entityType(EntityTypePredicate.of(BuiltInRegistries.ENTITY_TYPE, EntityTypes.ZOMBIE))
)
);

// make it exclusive with treasure enchantments
builder.exclusiveWith(registries.lookup(Registries.ENCHANTMENT).orElseThrow().getter().getOrThrow(EnchantmentTags.TREASURE));
}
}
);
Expand Down
Loading