燃料 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); |
测试
不要忘了贴图,然后我们就可以启动游戏去测试了











