mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-08 21:14:41 -04:00
Enchantment API (#3627)
* ALLOW_ENCHANTING event * Intrinsic enchantments + testmod also fixed a bug in the testmod that prevented the custom damage handler from ever working * Item-based override mechanism * Replaces part of the use cases of the event with a convenient method to override in FabricItem. * Updated and tested the testmod. * javadoc * Move event logic to FabricItemStack * oops * Simplify mixin * Replace ActionResult with TriState * Use TriState in testmod * requests * Clarify jdoc * Ship without intrinsic enchantments at first * Checkstyle * Checkstyle --------- Co-authored-by: modmuss50 <modmuss50@gmail.com>
This commit is contained in:
parent
6793dde117
commit
8f5205a8a1
12 changed files with 390 additions and 14 deletions
fabric-item-api-v1/src
main
java/net/fabricmc/fabric
api/item/v1
mixin/item
resources
testmod
java/net/fabricmc/fabric/test/item
resources/data/minecraft/tags/items
fabric-object-builder-api-v1/src/test/java/net/fabricmc/fabric/test/object/builder
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.item.v1;
|
||||
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
||||
/*
|
||||
* There is one context for each vanilla call to Enchantment#isAcceptableItem. The reason why RANDOM_ENCHANTMENT
|
||||
* feels like a kitchen sink is because it corresponds to the one in EnchantmentHelper, which is shared across multiple
|
||||
* uses.
|
||||
*
|
||||
* This also gets in the way of adding further context (nullable Player and BlockPos have been suggested
|
||||
* in the past). It's not impossible to do so, but a probably a bit more brittle.
|
||||
*/
|
||||
/**
|
||||
* An enum that describes the various contexts in which the game checks whether an enchantment can be applied to an item.
|
||||
*/
|
||||
public enum EnchantingContext {
|
||||
/**
|
||||
* When generating a random enchantment for the item. This includes the enchanting table, random
|
||||
* mob equipment, and the {@code enchant_with_levels} loot function.
|
||||
*
|
||||
* @see EnchantmentHelper#generateEnchantments(Random, ItemStack, int, boolean)
|
||||
*/
|
||||
RANDOM_ENCHANTMENT,
|
||||
/**
|
||||
* When trying to apply an enchantment in an anvil.
|
||||
*/
|
||||
ANVIL,
|
||||
/**
|
||||
* When using the {@code /enchant} command.
|
||||
*/
|
||||
ENCHANT_COMMAND,
|
||||
/**
|
||||
* When randomly enchanting an item using the {@code enchant_randomly} loot function without a list of enchantments
|
||||
* to choose from.
|
||||
*/
|
||||
LOOT_RANDOM_ENCHANTMENT
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.api.item.v1;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.event.Event;
|
||||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
||||
/**
|
||||
* Events relating to enchantments, allowing for finer control of what enchantments can apply to different items.
|
||||
*/
|
||||
public final class EnchantmentEvents {
|
||||
private EnchantmentEvents() { }
|
||||
|
||||
/**
|
||||
* An event that allows overriding whether an {@link Enchantment} can be applied to an {@link ItemStack}.
|
||||
*
|
||||
* <p>This should only be used to modify the behavior of <em>external</em> items with regards to <em>external</em> enchantments,
|
||||
* where 'external' means either vanilla or from another mod. For instance, a mod might allow enchanting a pickaxe
|
||||
* with Sharpness (and only Sharpness) under certain specific conditions.</p>
|
||||
*
|
||||
* <p>To modify the behavior of your own modded <em>enchantments</em>, use {@link Enchantment#isAcceptableItem(ItemStack)} instead.
|
||||
* To modify the behavior of your own modded <em>items</em>, use {@link FabricItem#canBeEnchantedWith(ItemStack, Enchantment, EnchantingContext)} instead.
|
||||
* Note that this event triggers <em>before</em> {@link FabricItem#canBeEnchantedWith(ItemStack, Enchantment, EnchantingContext)},
|
||||
* and that method will only be called if no listeners override it.</p>
|
||||
*
|
||||
* <p>Note that allowing an enchantment using this event does not guarantee the item will receive that enchantment,
|
||||
* only that it isn't forbidden from doing so.</p>
|
||||
*
|
||||
* @see AllowEnchanting#allowEnchanting(Enchantment, ItemStack, EnchantingContext)
|
||||
* @see Enchantment#isAcceptableItem(ItemStack)
|
||||
* @see FabricItem#canBeEnchantedWith(ItemStack, Enchantment, EnchantingContext)
|
||||
*/
|
||||
public static final Event<AllowEnchanting> ALLOW_ENCHANTING = EventFactory.createArrayBacked(
|
||||
AllowEnchanting.class,
|
||||
callbacks -> (enchantment, target, context) -> {
|
||||
for (AllowEnchanting callback : callbacks) {
|
||||
TriState result = callback.allowEnchanting(enchantment, target, context);
|
||||
|
||||
if (result != TriState.DEFAULT) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return TriState.DEFAULT;
|
||||
}
|
||||
);
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AllowEnchanting {
|
||||
/**
|
||||
* Checks whether an {@link Enchantment} should be applied to a given {@link ItemStack}.
|
||||
*
|
||||
* @param enchantment the enchantment that may be applied
|
||||
* @param target the target item
|
||||
* @param enchantingContext the enchanting context in which this check is made
|
||||
* @return {@link TriState#TRUE} if the enchantment may be applied, {@link TriState#FALSE} if it
|
||||
* may not, {@link TriState#DEFAULT} to fall back to other callbacks/vanilla behavior
|
||||
* @see EnchantingContext
|
||||
*/
|
||||
TriState allowEnchanting(
|
||||
Enchantment enchantment,
|
||||
ItemStack target,
|
||||
EnchantingContext enchantingContext
|
||||
);
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package net.fabricmc.fabric.api.item.v1;
|
||||
|
||||
import net.minecraft.component.type.AttributeModifiersComponent;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -107,6 +108,26 @@ public interface FabricItem {
|
|||
return ((Item) this).hasRecipeRemainder() ? ((Item) this).getRecipeRemainder().getDefaultStack() : ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the item is allowed to receive an {@link Enchantment}. This can be used to manually override what
|
||||
* enchantments a modded item is able to receive.
|
||||
*
|
||||
* <p>For example, one might want a modded item to be able to receive Unbreaking, but not Mending, which cannot be
|
||||
* achieved with the vanilla tag system alone. Alternatively, one might want to do the same thing with enchantments
|
||||
* from other mods, which don't have a similar tag system in general.</p>
|
||||
*
|
||||
* <p>Note that this method is only called <em>after</em> the {@link EnchantmentEvents#ALLOW_ENCHANTING} event, and
|
||||
* only if none of the listeners to that event override the result.</p>
|
||||
*
|
||||
* @param stack the current stack
|
||||
* @param enchantment the enchantment to check
|
||||
* @param context the context in which the enchantment is being checked
|
||||
* @return whether the enchantment is allowed to apply to the stack
|
||||
*/
|
||||
default boolean canBeEnchantedWith(ItemStack stack, Enchantment enchantment, EnchantingContext context) {
|
||||
return enchantment.isAcceptableItem(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fabric-provided extensions for {@link Item.Settings}.
|
||||
* This interface is automatically implemented on all item settings via Mixin and interface injection.
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
|
||||
package net.fabricmc.fabric.api.item.v1;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
||||
/*
|
||||
* Fabric-provided extensions for {@link ItemStack}.
|
||||
* This interface is automatically implemented on all item stacks via Mixin and interface injection.
|
||||
|
@ -36,4 +39,24 @@ public interface FabricItemStack {
|
|||
default ItemStack getRecipeRemainder() {
|
||||
return ((ItemStack) this).getItem().getRecipeRemainder((ItemStack) this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this {@link ItemStack} can be enchanted with the given {@link Enchantment}.
|
||||
*
|
||||
* <p>When checking whether an enchantment can be applied to an {@link ItemStack}, use this method instead of
|
||||
* {@link Enchantment#isAcceptableItem(ItemStack)}</p>
|
||||
*
|
||||
* @param enchantment the enchantment to check
|
||||
* @param context the context in which the enchantment is being checked
|
||||
* @return whether the enchantment is allowed to apply to the stack
|
||||
* @see FabricItem#canBeEnchantedWith(ItemStack, Enchantment, EnchantingContext)
|
||||
*/
|
||||
default boolean canBeEnchantedWith(Enchantment enchantment, EnchantingContext context) {
|
||||
TriState result = EnchantmentEvents.ALLOW_ENCHANTING.invoker().allowEnchanting(
|
||||
enchantment,
|
||||
(ItemStack) this,
|
||||
context
|
||||
);
|
||||
return result.orElseGet(() -> ((ItemStack) this).getItem().canBeEnchantedWith((ItemStack) this, enchantment, context));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.item;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.AnvilScreenHandler;
|
||||
import net.minecraft.screen.ForgingScreenHandler;
|
||||
import net.minecraft.screen.ScreenHandlerContext;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantingContext;
|
||||
|
||||
@Mixin(AnvilScreenHandler.class)
|
||||
abstract class AnvilScreenHandlerMixin extends ForgingScreenHandler {
|
||||
AnvilScreenHandlerMixin(@Nullable ScreenHandlerType<?> type, int syncId, PlayerInventory playerInventory, ScreenHandlerContext context) {
|
||||
super(type, syncId, playerInventory, context);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "updateResult",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/enchantment/Enchantment;isAcceptableItem(Lnet/minecraft/item/ItemStack;)Z"
|
||||
)
|
||||
)
|
||||
private boolean callAllowEnchantingEvent(Enchantment instance, ItemStack stack) {
|
||||
return stack.canBeEnchantedWith(instance, EnchantingContext.ANVIL);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.item;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.server.command.EnchantCommand;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantingContext;
|
||||
|
||||
@Mixin(EnchantCommand.class)
|
||||
abstract class EnchantCommandMixin {
|
||||
@Redirect(
|
||||
method = "execute",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/enchantment/Enchantment;isAcceptableItem(Lnet/minecraft/item/ItemStack;)Z")
|
||||
)
|
||||
private static boolean callAllowEnchantingEvent(Enchantment instance, ItemStack stack) {
|
||||
return stack.canBeEnchantedWith(instance, EnchantingContext.ENCHANT_COMMAND);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.item;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.function.EnchantRandomlyLootFunction;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantingContext;
|
||||
|
||||
@Mixin(EnchantRandomlyLootFunction.class)
|
||||
abstract class EnchantRandomlyLootFunctionMixin {
|
||||
@Redirect(
|
||||
method = "method_53327",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/enchantment/Enchantment;isAcceptableItem(Lnet/minecraft/item/ItemStack;)Z")
|
||||
)
|
||||
private static boolean callAllowEnchantingEvent(Enchantment instance, ItemStack stack) {
|
||||
return stack.canBeEnchantedWith(instance, EnchantingContext.LOOT_RANDOM_ENCHANTMENT);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.item;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantingContext;
|
||||
|
||||
@Mixin(EnchantmentHelper.class)
|
||||
abstract class EnchantmentHelperMixin {
|
||||
@Redirect(
|
||||
method = "getPossibleEntries",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/enchantment/Enchantment;isAcceptableItem(Lnet/minecraft/item/ItemStack;)Z")
|
||||
)
|
||||
private static boolean useCustomEnchantingChecks(Enchantment instance, ItemStack stack) {
|
||||
return stack.canBeEnchantedWith(instance, EnchantingContext.RANDOM_ENCHANTMENT);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,11 @@
|
|||
"compatibilityLevel": "JAVA_17",
|
||||
"mixins": [
|
||||
"AbstractFurnaceBlockEntityMixin",
|
||||
"AnvilScreenHandlerMixin",
|
||||
"BrewingStandBlockEntityMixin",
|
||||
"EnchantCommandMixin",
|
||||
"EnchantmentHelperMixin",
|
||||
"EnchantRandomlyLootFunctionMixin",
|
||||
"ItemMixin",
|
||||
"ItemSettingsMixin",
|
||||
"ItemStackMixin",
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
package net.fabricmc.fabric.test.item;
|
||||
|
||||
import net.minecraft.component.DataComponentType;
|
||||
import net.minecraft.enchantment.Enchantment;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.enchantment.Enchantments;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.PickaxeItem;
|
||||
import net.minecraft.item.ToolMaterials;
|
||||
import net.minecraft.network.codec.PacketCodecs;
|
||||
|
@ -30,21 +34,14 @@ import net.minecraft.util.dynamic.Codecs;
|
|||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.item.v1.CustomDamageHandler;
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantingContext;
|
||||
import net.fabricmc.fabric.api.item.v1.EnchantmentEvents;
|
||||
import net.fabricmc.fabric.api.registry.FuelRegistry;
|
||||
import net.fabricmc.fabric.api.util.TriState;
|
||||
|
||||
public class CustomDamageTest implements ModInitializer {
|
||||
public static final Item WEIRD_PICK = new WeirdPick();
|
||||
public static final DataComponentType<Integer> WEIRD = Registry.register(Registries.DATA_COMPONENT_TYPE, new Identifier("fabric-item-api-v1-testmod", "weird"),
|
||||
DataComponentType.<Integer>builder().codec(Codecs.NONNEGATIVE_INT).packetCodec(PacketCodecs.VAR_INT).build());
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, new Identifier("fabric-item-api-v1-testmod", "weird_pickaxe"), WEIRD_PICK);
|
||||
FuelRegistry.INSTANCE.add(WEIRD_PICK, 200);
|
||||
// TODO 1.20.5
|
||||
// FabricBrewingRecipeRegistry.registerPotionRecipe(Potions.WATER, Ingredient.ofItems(WEIRD_PICK), Potions.AWKWARD);
|
||||
}
|
||||
|
||||
public static final CustomDamageHandler WEIRD_DAMAGE_HANDLER = (stack, amount, entity, slot, breakCallback) -> {
|
||||
// If sneaking, apply all damage to vanilla. Otherwise, increment a tag on the stack by one and don't apply any damage
|
||||
if (entity.isSneaking()) {
|
||||
|
@ -54,6 +51,25 @@ public class CustomDamageTest implements ModInitializer {
|
|||
return 0;
|
||||
}
|
||||
};
|
||||
// Do this static init *after* the damage handler otherwise it's still null while inside the constructor
|
||||
public static final Item WEIRD_PICK = new WeirdPick();
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
Registry.register(Registries.ITEM, new Identifier("fabric-item-api-v1-testmod", "weird_pickaxe"), WEIRD_PICK);
|
||||
FuelRegistry.INSTANCE.add(WEIRD_PICK, 200);
|
||||
// TODO 1.20.5
|
||||
// FabricBrewingRecipeRegistry.registerPotionRecipe(Potions.WATER, Ingredient.ofItems(WEIRD_PICK), Potions.AWKWARD);
|
||||
EnchantmentEvents.ALLOW_ENCHANTING.register(((enchantment, target, enchantingContext) -> {
|
||||
if (target.isOf(Items.DIAMOND_PICKAXE)
|
||||
&& enchantment == Enchantments.SHARPNESS
|
||||
&& EnchantmentHelper.hasSilkTouch(target)) {
|
||||
return TriState.TRUE;
|
||||
}
|
||||
|
||||
return TriState.DEFAULT;
|
||||
}));
|
||||
}
|
||||
|
||||
public static class WeirdPick extends PickaxeItem {
|
||||
protected WeirdPick() {
|
||||
|
@ -77,5 +93,11 @@ public class CustomDamageTest implements ModInitializer {
|
|||
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeEnchantedWith(ItemStack stack, Enchantment enchantment, EnchantingContext context) {
|
||||
return context == EnchantingContext.ANVIL && enchantment == Enchantments.FIRE_ASPECT
|
||||
|| enchantment != Enchantments.FORTUNE && super.canBeEnchantedWith(stack, enchantment, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"fabric-item-api-v1-testmod:weird_pickaxe"
|
||||
]
|
||||
}
|
|
@ -20,10 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
|||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import net.minecraft.entity.SpawnLocation;
|
||||
|
||||
import net.minecraft.entity.SpawnLocationTypes;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
|
@ -33,6 +29,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.SpawnGroup;
|
||||
import net.minecraft.entity.SpawnLocationTypes;
|
||||
import net.minecraft.entity.SpawnRestriction;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeContainer;
|
||||
import net.minecraft.entity.attribute.DefaultAttributeRegistry;
|
||||
|
|
Loading…
Add table
Reference in a new issue