自定义实体 | Paper插件开发
自1.17之后, SpigotMC 开始提供 Mojang 混淆表版本的 Spigot 服务端,这意味着大大简化了开发难度 —— 不需要再对照混淆表一个一个看NMS 方法名
本篇我来介绍使用Paper API的插件如何使用Mojang mappings自定义实体
引入依赖
这里使用Gradle Groovy讲解
这里有用Gradle Kotlin的例子
https://github.com/PaperMC/paperweight-test-plugin/
一共要改两处地方
1 | plugins { |
1 | pluginManagement { |
创建自定义实体
很明显,根据已有的API,甚至是Paper API,都没有向我们提供创建自定义实体的功能。因此,想要创建自定义实体,需要使用 Mojang mappings
我们刚才依赖引入的就是(1.17- 需要使用NMS
)
本例中,我们创建一个不会被破坏,只能坐一个玩家的船(不是箱船),来自我的项目 – IceBoat
继承已有实体
让我们创建 GameBoat 类,继承 net.minecraft.world.entity.vehicle.Boat 类
1 | public class GameBoat extends Boat {} |
接下来,初始化该实体,实现超类构造器
1 | public class GameBoat extends Boat { |
要想生成该实体,则应该调用 Boat#setPos(x,y,z)
设置坐标,然后调用 ServerLevel#addFreshEntityWithPassengers(Entity)
方法生成实体。为了简便流程,我们可以自定义一个可传入 Bukkit Location
的构造函数,使其调用后自动在设定坐标生成
1 | public GameBoat(Location location) { |
然后你就可以看到你自定义的船实体了
继续修改
只能一个玩家乘坐
我们观察 net.minecraft.world.entity.vehicle.Boat
的源码,可以发现乘坐调用的是 Boat#addPassenger(Entity)
,所以我们重写这个方法就行
1 |
|
既然Passengers(List<Entity>)
只有一个,那我们可以顺便写个获取获取乘坐者的方法
1 | public org.bukkit.entity.Player getPassenger() { |
哦,对了如果你想addPassenger
的话,我们可以再写个方法
1 | public void addPassenger(org.bukkit.entity.Player player) { |
修改Tick
重写tick()
就行,别忘记加上super.tick();
,除非你真的想彻底更改这个实体
1 |
|
一些有用的互转
1 | Entity entityPlayer = ((CraftPlayer) xxx).getHandle(); |
1 | ServerLevel level = ((CraftWorld) xxx.getWorld()).getHandle(); |
编译
(踩坑 +1)
你现在不是用 gradle build
来编译插件了,应改用paperweight提供的reobfJar
也就是命令变成了 gradle reobfJar