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
相关产品推荐
相关产品推荐

