MCBBS Wiki欢迎您共同参与编辑!在参与编辑之前请先阅读Wiki方针。
如果在编辑的过程中遇到了什么问题,可以去讨论板提问。
为了您能够无阻碍地参与编辑 未验证/绑定过邮箱的用户,请尽快绑定/验证。
MCBBS Wiki GitHub群组已上线!
您可以在回声洞中发表吐槽!
服务器状态监控。点击进入
本站由MCBBS用户自行搭建,与MCBBS及东银河系漫游指南(北京)科技有限公司没有从属关系。点此了解 MCBBS Wiki 不是什么>>
用户:MashKJo/1.12.2模组开发教程/14.高级物品(二) - 武器和工具
武器和工具体系,是Minecraft的一大特色。原版中武器包括剑和弓箭,工具则包括镐、斧、铲、锄、剪刀。若我们想给模组添加新的武器和工具,通常只需复用原版写好的类即可。
小提示:武器/工具的物品模型文件,其父模型应该设定为minecraft:item/handheld
。
工具质地(ToolMaterial)
剑和绝大部分工具的类的构造参数都需要一个Item.ToolMaterial参数,该类是一个枚举类,用于指定该武器/工具的质地——木质、石质、铁质等等,和Material一样,该类用于封装武器/工具的一些固有属性,如:伤害加成、挖掘速度、附魔能力等等。原版提供了5种ToolMaterial,作为Modder,我们肯定有自定义工具质地的需求,但枚举类是不能在除它之外的地方产生新实例的,那么怎么办? Forge提供了一个名为EnumHelper的类来解决“给枚举类在其之外的地方产生新实例”这种需求,原理自然是反射等一系列黑魔法。
我们只需这么写:
public static final Item.ToolMaterial MY_CUSTOM_TOOL_MATERIAL = EnumHelper.addToolMaterial(name, harvestLevel, maxUses, efficiency, damage, enchantability);
name即该ToolMaterial的名称,为小写字母+下划线的形式;harvestLevel为该质地对应工具的挖掘等级;maxUses即最大耐久值;efficiency为该质地对应工具的挖掘速度;damage代表该质地对于攻击伤害的加成——注意,是该质地的加成,不是具体的武器/工具的加成,实际上后者还会有一个额外加成,因此在没有其他因素干扰时,玩家手持武器/工具造成的伤害为:空手伤害(1)+质地加成的伤害+武器/工具对应的种类加成的伤害;enchantability代表该质地对应的武器/工具获得优秀附魔的能力,是一个int整数,值越大该能力越强。 上述有些数值,如果读者觉得有些拿不准,先看看原版的5个ToolMaterial在这里填写的数值都是什么,方便读者自行取舍填入的数值。
然而,新的ToolMaterial并非必须——它只是对武器/工具的一些固有属性的封装,我们可以通过覆写类下一些方法来达到同样的效果,因此如果你只是制作单一的武器/工具而非一整套,你也大可胡乱填入一个ToolMaterial,并覆写父类下一系列方法来实现更精细的调控。
新的武器
剑
所有的剑都是ItemSword类的实例,简单复用该类即可。你可以通过覆写MultiMap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot)
方法来实现自定义剑的攻击伤害,这块涉及到生物属性和属性修饰符的知识,详见后续教程。
盾牌
盾牌对应的类是ItemShield,我们可以先继承再实例化;不过Forge给了我们一个更为灵活的方案:覆写Item#isShield
方法即可。该方法是Forge patch进Item类的,这样我们就可以让一个物品对应的类不必继承于ItemShield类而拥有盾牌的特性。
弓箭
弓对应的类是ItemBow类,你可以通过继承该类来创建和原版不相同的弓,通过覆写方法,你可以定义:该弓所使用的箭矢满足的条件,拉弓至满弦的时长,弓箭被发出时的初速度等。弓所能决定的东西也差不多只有这些,至于发出的箭矢打在实体上造成的效果,那是由EntityArrow决定的。 原版的箭矢物品对应的类是ItemArrow,但它只有2个方法,且都是配合着ItemBow用的辅助方法,因此新的箭矢物品你完全可以直接new Item类即可,重点在于箭矢实体。我们没必要创建EntityArrow的子类,除非真的有特殊需求。我们完全可以直接复用EntityArrow类,然后我们监听ProjectileImpactEvent.Arrow事件,从该事件中我们能获取箭矢实体本身,以及一个RayTraceResult,由此我们就能实现我们想要实现的自定义逻辑。那么如果我们需要获取发射出该EntityArrow的弓的信息怎么办?很简单,射出该箭矢时给对应的EntityArrow上个NBT就好了。关于实体的知识,详见后续教程。
新的工具
ItemTool
这块可能有点反直觉——虽说这个类叫ItemTool,但是只有ItemPickaxe、ItemSpade和ItemAxe三个类继承了该类——即镐、铲和斧。简单复用这三个类即可创建新的镐、铲或斧。
如果你想创建新的工具类型,可以选择继承ItemTool类。该工具能挖掘什么样的方块而产生掉落物,你可以通过覆写boolean canHarvestBlock(IBlockState state)
来实现。有读者可能要问:走Forge提供的那套setHarvestLevel机制不行吗?确实可行,覆写Item类下的getHarvestLevel和getToolClasses这2个方法即可,注意后者返回的是一个Set<String>,也就是说你的新工具类型实际上可以代表不止一种“采掘类型”。
锄、剪刀以及其他
锄和剪刀对应的类分别是ItemHoe和ItemShears。ItemHoe没有作为工具的通用行为,它没有对应的toolClass,也不会加速任何方块的破坏或造成任何方块的掉落,唯一的作用就是右键把泥土变成耕地。因此,与其说它是一种工具类型,不如说只是一种特殊的物品罢了。 而ItemShears则比较有趣,经由Forge的一番patch之后,剪刀在破坏方块或右键与实体交互时,会检查它们是否实现了IShearable接口,如果是,则执行接口所规定的方法。因此,如果你想创建新的带有特殊逻辑的剪刀,且特殊逻辑仅涉及你自己新增的方块/实体,那么你甚至都不需要搞个子类,直接new ItemShears类,再让你的方块/实体实现IShearable接口,实现的时候判断一下ItemStack的物品种类即可。 剪刀在挖掘特定方块(蜘蛛网、羊毛等)时速度较快或可以产生掉落物等行为,是因为它覆写了canHarvestBlock和getDestroySpeed方法。 所以你在创建新的工具物品的时候,如果它和剪刀一样,挖掘方块的情况很多都是特例,那么就不用继承ItemTool类,模仿ItemShears的思路直接继承Item类,再覆写一些方法即可。