前言
在做弹幕踪迹台之前,首先得拿到mc内所有的粒子类型来让玩家选择。
mc原版粒子都在ParticleTypes类内,只需要把这个类里面所有的静态对象穷举为一个列表,即可解决问题,但这么做显然非常不优雅,而且,不兼容其他模组添加到粒子
当然也有planB,通过AccessTransformer,在ParticleEngine中拿到私有对象providers,是的,所有粒子也会在这里注册一遍。
附录:
1.显然,你需要一个Particle类,负责粒子的具体逻辑;
2.我们当然还需要指定粒子对应的ParticleType,这样才能知道谁是谁;
3.还要一个ParticleOption,这样才能方便粒子生成的消息通过网络传输,以及指令生成;
4.一个ParticleProvider,类似一个工厂类,将ParticleOption转换为Particle。
生成一个粒子要找四家,真不愧是你啊,麻将
正文
我想到mc原版指令Particle有一个命令提示,那里拿到了全部的粒子。然后顺藤摸瓜找到了ParticleArgument类的particles字段,它在初始化的时候拿到了所有注册在Registries.PARTICLE_TYPE下的ParticleType<?>。看到这里,我感觉这个就是我需要的东西。
下面就是打断点,看调用链,找到是哪个方法初始化了这个字段,找到了HolderLookup类的lookupOrThrow方法,传入一个ResourceKey<? extends Registry<? extends T>>对象,但这里似乎已经走进了一个死胡同,我该怎么调用这个方法呢
功夫不负有心人,我找到这个方法的实现方法,RegistryAccess类的lookupOrThrow方法,可以向它直接传入Registries.PARTICLE_TYPE
在给这个方法打断点寻找后,按着调用链,找到了RegistryLayer类的静态方法createRegistryAccess(),再调用compositeAccess返回一个列表内有全部注册表对象的RegistryAccess对象
万事俱备,只需如下代码即可拿到所有的粒子,顺便打印出来
1 | public static void getParticle() { |
后面经过我的寻找,找到了一个弃用方法拿到对应注册表种类的对象
1 |
|
打印部分结果如下
1 | ResourceKey[minecraft:particle_type / minecraft:ambient_entity_effect] |