You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Minecraft Forge 1.12.2:给原版物品加NBT标签设置最大耐久的方法

嘿,作为模组开发新手能想到用NBT扩展原版物品功能,这思路很棒!我来帮你搞定给原版工具、防具自定义最大耐久的需求,分基础实现和更简便的方案来讲:

核心实现思路:拦截原版耐久计算逻辑

Forge提供了专门的事件来修改物品堆的最大耐久,不需要修改原版物品的源码,只需要监听事件并替换值就行,这是最稳妥的方式。

1. 注册最大耐久修改事件监听器

我们要监听ItemStackEvent.GetMaxDamage事件,这个事件会在游戏获取物品最大耐久时触发。在你的模组事件订阅类里添加以下代码:

import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.nbt.CompoundNBT;
import net.minecraftforge.event.ItemStackEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = "your_mod_id", bus = Mod.EventBusSubscriber.Bus.FORGE)
public class DurabilityEventHandler {

    @SubscribeEvent
    public static void onGetMaxDamage(ItemStackEvent.GetMaxDamage event) {
        ItemStack stack = event.getStack();
        Item item = stack.getItem();
        
        // 只处理继承ItemTool或ItemArmor的物品
        if (item instanceof ItemTool || item instanceof ItemArmor) {
            // 检查是否存在自定义"durability" NBT标签
            if (stack.hasTag() && stack.getTag().contains("durability", net.minecraft.nbt.Tag.TAG_INT)) {
                // 用NBT中的值覆盖默认最大耐久
                event.setMaxDamage(stack.getTag().getInt("durability"));
            }
        }
    }
}

2. 游戏内设置NBT标签的方式

你需要一个途径给物品添加这个标签,最直接的是做一个自定义命令,让玩家手持物品时执行命令来设置耐久。示例代码如下:

import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommandSender;
import net.minecraft.command.WrongUsageException;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemArmor;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemTool;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.event.RegisterCommandEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = "your_mod_id", bus = Mod.EventBusSubscriber.Bus.FORGE)
public class DurabilityCommandHandler {

    @SubscribeEvent
    public static void registerCommands(RegisterCommandEvent event) {
        event.getDispatcher().register(new SetDurabilityCommand());
    }

    public static class SetDurabilityCommand extends CommandBase {
        @Override
        public String getName() {
            return "setdurability";
        }

        @Override
        public String getUsage(ICommandSender sender) {
            return "commands.setdurability.usage";
        }

        @Override
        public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
            if (args.length != 1) {
                throw new WrongUsageException("commands.setdurability.usage");
            }

            EntityPlayer player = getCommandSenderAsPlayer(sender);
            ItemStack heldStack = player.getHeldItemMainhand();

            // 检查手持物品是否是目标类型
            if (heldStack.isEmpty() || !(heldStack.getItem() instanceof ItemTool || heldStack.getItem() instanceof ItemArmor)) {
                throw new CommandException("commands.setdurability.invalid_item");
            }

            int newDurability = parseInt(args[0], 1); // 确保耐久至少为1

            // 初始化NBT标签(如果没有的话)
            if (!heldStack.hasTag()) {
                heldStack.setTag(new CompoundNBT());
            }
            heldStack.getTag().putInt("durability", newDurability);

            // 给玩家反馈
            notifyCommandListener(sender, this, "commands.setdurability.success", newDurability);
        }
    }
}

记得在你的语言文件(lang/en_us.json)里添加命令的本地化文本:

{
  "commands.setdurability.usage": "Usage: /setdurability <amount>",
  "commands.setdurability.invalid_item": "You must hold a tool or armor item!",
  "commands.setdurability.success": "Set item max durability to %d"
}
更简便的优化方案

其实上面的事件监听已经是很简便的方式了,因为它完全基于Forge的事件系统,不需要修改原版代码。如果想进一步简化,可以:

  • 把事件监听和命令注册整合到同一个类里,减少代码分散
  • 如果需要批量设置物品耐久,可以扩展命令支持指定物品ID,不过对新手来说先实现手持物品的版本就足够了

另外要注意:

  • 自定义耐久的物品丢地上再捡起来,NBT标签会自动保留,因为ItemStack的序列化会完整保存所有标签
  • 物品的耐久条会自动适配你设置的NBT值,不需要额外处理显示逻辑

内容的提问来源于stack exchange,提问作者user20984643

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:10:48