燃料 1.20 Fabric 长线教程计划
本篇教程的视频
本篇教程的源代码
GitHub地址:TutorialMod-Fuel-1.20.1
本篇教程目标
- 学会使用
Fabric API
为模组添加燃料
- (选做)初步使用
Mixin
,添加燃料
查看源代码
虽然我们可以直接使用Fabric API
来添加燃料,但为了使用Mixin
,我们还是需要查看源代码
这里我们先来找找原版的那些燃料,以COAL
为例
1 | public static final Item COAL = register("coal", new Item(new Item.Settings())); |
这是Items
类中,COAL
的注册,但它和别的物品一样,没有什么特别之处
这个时候,我们就得看它用在哪里了
CTRL + ALT + F7
,查找所有引用COAL
的地方
排除其他的一些类之后,我们就可以锁定到AbstractFurnaceBlockEntity
这个类了
AbstractFurnaceBlockEntity类
这个是游戏中熔炉
、高炉
这些方块实体的基类,当然我们今天的重点不在方块实体上,我们看到这里面引用COAL
的地方
1 | public static Map<Item, Integer> createFuelTimeMap() { |
我们看到一个createFuelTimeMap
方法,这个方法返回一个Map
,里面存储了所有燃料的物品
和对应的燃烧时间
就像这里的COAL
,燃烧时间是1600tick
(熔炉),也就是80秒
addFuel方法
addFuel
方法就是向这个Map
里面添加燃料的,我们来看看这个方法
1 | private static void addFuel(Map<Item, Integer> fuelTimes, ItemConvertible item, int fuelTime) { |
这个方法很简单,本质就是最后的那个put
方法,向Map
里面添加燃料
当然如果这个物品是不能燃烧的木头物品,那么就会抛出一个异常,否则就会向Map
里面添加燃料
然鹅,可惜的是,原版并没有为我们提供直接添加燃料的方法,它都已经在createFuelTimeMap
方法中直接写死了
要想将我们的物品也加到这里来,就得使用Mixin
了
Mixin简述
Mixin
的官方Wiki
:Mixin Wiki
Fabric Wiki
上的Mixin
教程:Fabric Wiki - Mixin
Mixin
的相关内容可以参考这两个链接,其官方Wiki
是对Mixin
原理的解释,并不是教程
现在,我们来聊聊这个Mixin
。首先看这个词,Mixin
,翻译过来就是混入
,其实质就是将我们的一部分代码混入到源代码
之中,这是Mixin
最基本的功能
那我们何时采用Mixin呢?
假设说,你在开发过程中,哎!觉得源代码里面有个方法写的挺好(也可能是你必须得用这个方法)
但是嘞,它那个方法层层叠叠,又调了本类或者其他类的方法,或者说它本类里面的私有字段……反正就是一堆,并不像我们注册物品和方块那样简单,直接搬源代码里的方法就行
要想把那个方法完整写好,就得搬其他的杂七杂八的方法,就变成了“为了一碗醋包了一盘饺子”,而且大多数情况下是不好搬的。它会拖泥带水,带一堆杂七杂八的方法或者字段
这个时候,你可能就需要考虑Mixin了
就像我们这里的这个createFuelTimeMap
方法,它这里的addFuel
又是另一个方法,而且是私有
的……这时,我们得用Mixin
了
另外的情况就是你想修改游戏的一些机制,比如粒子上限;或者说拦截一些事件,或者增加某些功能,这个时候也可以考虑Mixin
最后,还是那句话,在使用Mixin
之前,请确保你对你要修改的目标类及其相关的类足够熟悉
,不然很容易写崩
添加燃料
燃料物品注册
我们先完成前面的操作,再来整后面的那些东西
先来注册物品
1 | public static final Item ANTHRACITE = registerItems("anthracite", new Item(new Item.Settings())); |
加入物品栏
别忘了将物品加入物品栏
1 | entries.add(ModItems.ANTHRACITE); |
使用Mixin添加燃料
Minecraft Development
这个插件可以装一下,它提供了对Mixin
的支持
这里我们创建一个AbstractFurnaceBlockEntityMixin
类
并使用@Mixin
注解,指向目标类AbstractFurnaceBlockEntity
1 |
|
这个类要添加到<modid>.mixins.json
文件中,也可以用插件来自动添加
1 | { |
接下来我们就要这里面写一些方法
这里我们要使用@Inject
注解,这个注解是注入
代码到目标方法
1 |
|
method
是注入的目标方法,目标方法自然是我们上面提到的createFuelTimeMap
at
是注入的位置,TAIL
表示在目标方法最后
,但在return
之前注入代码
cir
是回调信息,它里面包含了目标方法的一些信息,比如返回值等,这个可以利用插件来补全
cir.getReturnValue()
获取返回值
,在createFuelTimeMap
方法中,就是那个map
,
这里我们直接将我们的物品加入进去,燃烧时间设置为1600tick
这样,我们就完成了一个燃料的注册
当然,这里我们是直接绕开了addFuel
方法,更严谨一点应该是要调用这个方法的
不过,如果你能保证不把原版不能燃烧的东西加进去,也无伤大雅
这里的这个Mixin
案例比较简单,并没有涉及到其他的复杂的东西,
我讲的也不是非常详细,Mixin
这个东西,还是得自己实践,多写写也就会了
Fabric API添加燃料
那么Mixin
不会写,我们就拿现成的API
来写吧
Fabric的本质也就是Mixin
,只是它给我们封装好方法了,用就完了
我们到模组主类的onInitialize
方法中写上
1 | FuelRegistry.INSTANCE.add(ModItems.ANTHRACITE, 1600); |
这样,我们就完成了一个燃料的注册
很简单对吧,不过你去看它底层,本质就是Mixin
,不过用API
要比我们自己写简单得多
两个方法取一个你自己喜欢的来写就好了
资源文件
语言文件数据生成
1 | translationBuilder.add(ModItems.ANTHRACITE, "Anthracite"); |
物品模型数据生成
1 | itemModelGenerator.register(ModItems.ANTHRACITE, Models.GENERATED); |
测试
不要忘了贴图
,然后我们就可以启动游戏去测试了