本期教程我们来讲一下如何修改战利品表。首先,我们有一个需求,即添加一个兑换券,使得当我们使用带有时运附魔的工具挖掘石头时,可以掉落兑换券。
一个更符合原版的方法是在资源包中创建一个名为"data"的文件夹,然后覆盖"MINECRAFT"命名空间下的关于石头的战利品表,即"data/minecraft/loot_tables/blocks/stone.json"。在这个战利品表中,我们可以添加我们自己的物品。
然而,这种做法存在一个问题:如果其他mod也想修改关于石头的战利品表,那么谁会生效取决于加载顺序。后加载的mod会覆盖前一个mod的数据,这会导致互相之间的不兼容。
因此,我们不应该直接覆盖战利品表,除非这是你自己的mod。如果你想修改原版或其他mod的战利品表,应该使用Forge提供的修改战利品表的方法,即"global loot modifiers"。
这个方法需要创建两个文件,并通过类继承"GlobalLootModifierSerializer"类来实现。这两个文件也可以通过数据生成器来生成,手写起来也不难。
首先,按照指导创建一个软件包,命名为"root_mod_fire"。然后创建一个Java类,命名为"ModModifier",并继承"GlobalLootModifierSerializer"类。在实现方法中创建构造函数,并实现"doApply"方法来对战利品表进行修改。我们还需要一个CODEC对象,用于注册到"RegistryObject"中,以便在注册时调用。
我们需要为我们的"LOModFire"类提供一些参数。在修改战利品表时,我们应该尽量不要硬编码数据,而是应该让这些参数可配置化。这样其他人就可以通过数据包来更改我们的配置,从而自定义他们的游戏体验。因此,我们需要传入一些参数,例如掉落的物品数量和概率。
我们这里只是简单地修改石头的战利品表,让它掉落兑换券。我们可以定义一个私有的最终整数变量"num",并在构造函数中进行初始化。这里我们使用一个静态变量来存储"CODEC",以便在需要的时候返回。然后,我们创建一个静态的Supplier接口的变量来存储"CODEC",并将其泛型设置为"KODAK",即战利品表修改器的类型。
接下来,我们需要实现"doApply"方法来对战利品表进行修改。我们需要修改传入的"loot"对象,然后返回它。如果需要检查环境方面的信息,可以使用"Context"对象。
在"Context"对象下,我们可以使用"getLuck"方法来获取玩家的幸运值,使用"getLevel"方法来获取世界的信息。通过"getLevel"方法,我们可以进行非常大量的修改。但在这里,我们只需要简单地让更多的兑换券掉落,因此我们直接使用"GenderSuit"。
对于战利品表的修改,我们可以直接操作"JanuaryLoot"对象。这个对象是"ObjectArrayList"类的实例,而"ObjectArrayList"类又是继承自"AbstractObjectCollection",而后者又是继承自"AbstractCollection",以此类推,这都是Java原生提供的集合接口,所以我们可以按照正常的集合操作方法去操作它。我们可以直接使用"add"方法将要掉落的物品添加到列表的末尾。在添加物品时,我们可以使用"TestMod"中的"ExchangeCoupon",如果需要使用其他Mod中的物品,可以通过Forge的注册表来获取。记得在使用其他Mod的物品之前要检查另一个Mod是否存在,以避免报错。
完成对战利品表的修改后,我们可以删除导入的演示用代码。至此,我们的"StoneLootModifier"就完成了。
接下来,我们需要创建数据生成器。在"data"文件夹下,我们可以新建一个Java类"GlobalRootModifier"。然后,我们可以参考文档中的生成器部分,例如"Theater Generators"和"GlobalLootModFireGenerator"。
接下来我们需要继承一个类,那我们就继承过来。然后导入类,实现方法,创建构造函数。在这个"start"方法里面,我们直接写"add",然后给我们的这个"modifier"起个名字,比如说兑换券,然后"by",停止实例。那这里我们就直接传入我们这"StoneModFier"的实例就好了。New "StoneModifier",然后这里的参数就是我们刚才这里需要的这个"rootItemCondition",还有一个"int nb"。那我们就new "RootItemCondition"。然后下一个参数是我们的默认值。
默认值是假如说就三吧,我们就写三。然后把根刚才这边的构造函数设成public,这样我们这边就能访问了。然后这个"condition"它这里有一个实例,比如说天气检查。如果是雨天,对吧,这里是一个智力好。那我们可以在这个"ConditionalLoadedData"里面看到这个"conditions"的一些介绍。这里面所有的条件都会按的在一起。那如果我们不知道这个"condition"在哪呢?我们也可以去原版的里面找啊。我们可以在这个点这个找到它,然后这里找到这个"predicate",然后看这里有一个,这里就有它的包啊,它就在这个位置。我们直接点过去好,这里就是我们所有能用的"condition"。
我们就找一个就行了,假如说我们是想要让石头能掉落,那我们的条件肯定是方块得是得透嘛,对吧?好,我们就可以找到这个"RootItemBlockSeedPropertyCondition",好我们就用它就"RootItemBlockStatePropertyCondition",然后点"hasBlockStateProperties",这里传入我们的方块就行了。那这里的方块呢,我们就需要使用原版的这个"Blocks"点"STONE"。最后我们还要点"build"。如果我们还需要其他条件,我们也可以写,比如说我们这里有一个匹配工具,那我们可以写"matchTo"点"TOMATCHES"。
我们可以看看这个"TOMATCHES",它的调的参数是"itemPredicate",那我们就找到这个"itemPredicate",看看它在哪啊,他这个"net.minecraft.advancement.CriterionTrigger",这里就有我们的这个"predicate"了,那我们主要来看这个"itemPredicate"有哪些方法,我们需要的是验证这个工具上的附魔有没有时运,当然看不懂也没有关系,我们可以通过右键查找用法,然后我们就可以在库里面找到很多用法,我们可以找到"新实例创建"或者"嵌套类访问",可以看到它这里是怎么写的,他这里有这个"itemPredicate"点"builder",点"item"点"of"什么,然后点"build",我们就学着他写就行了,主要还是学看看原版是怎么写的,然后我们就照着写,那我们就写"itemPredicate"点"builder",点"item",我们发现这里就有很多的方法了,我们就可以"hasEnchantment",然后这里又需要这个"enchantmentPredicate"。
我们再来进这个"enchantmentPredicate"里面,然后再查找用法,然后这里没有嵌套类访问,只有这个"新势力创建","新势力创建",它看起来就是直接使用构造方法的,那我们就"new enchantmentPredicate",原版的关于附魔的注册类就是这个"Enchantment",如果你是自己创建的附魔,就要找你自己的附魔的注册类,其他mod的就是在"forge"类里面找。
首先是关于"FORTUNRESISTANCE"的重构,之后再说吧。然后是"tenement"点"block"的"fortune"就是10月了。然后这里需要等级啊,这里有这个"me max bx"。这里是"me max bts"点"ins"。我们就一步一步这样找过去,然后就写这个"me max bts"点"ins"点。然后这里我们可以找到有"at least"最少"at mod",最多"between"在什么之间。我们就至少二级就十运二,最后再点"build",然后最后再点"build"。然后稍微换个行,这样看起来舒服一点。
这个也写完了。我们最后再找到我们的"data generator"里面,把我们的这个东西注册进去。我们需要"generator at provider event",点"include server",new "global root modifier"。我无法把mod id放进去。好到这里还没完。我们最后别忘了,之前我们这个这里是要注册到这个boss的注册表里面的,这个不能忘了。然后就需要"defer registers",这个就给他复制过来。public static finale这个导入类,然后这个口袋可以不要导入错了。
这个"com.mod.realizations"这个"CODEC",然后这里就写"global roots modifier"等于"defer register"点"create"好,那这个是独属于forge的东西,所以我们要用"forge registries"点"is global root modifier realizers",然后mod id好,然后我们就在这里就可以写"public static final regime object"。
好,这里他这里写的是KODAK啊,这里是我们的"mod fied"的那个类啊,那我们就写"kodak stm root modifier","stone note"等于"global loot modifiers in register",然后名字一样就行,然后这里要传入的是那个KODAK,我们就直接"stone ot fortifier"点"CODEC"好,然后不要忘了在这个里面,我们还需要这个"global root mod fiers"点"register bus"好。这下就算是彻底搞定了。
我们首先需要run data,让他把这个数据生成出来。运行完之后,我们就可以在这里看到,它为我们生成了这个"global root mod fires",然后在这个"root modifiers"里面生成这个兑换券白丝洞。这里的这些东西"condition"都给我们生成好了。
那我们就来测试一下到底有没有生效吧。进来之后,我们已经在这里放好了很多的石头,又来测试了。然后我们这几把稿子,这这是普通的稿子,然后这个呢我们给它附魔上这个时运一,这个呢我们给它附上时运二,然后这个呢我们给它附上效率三。好我们切成生存模式来看看效果,首先这个普通稿子应该敲这些东西都没有用,然后时运一应该也不行。
你看敲普通石头掉出了这个兑换券了,然后掉多少呢,掉了三个,没错吧,然后这个风力当然也是没有用的了,那我们就成功的对这个战利品表进行修改了。为什么我们需要使用这种数据的形式呢?把看这里有一个NM3,这就是我们生成出来的三,并不是他写死了三。
如果其他的mod或者数据包作者想要更改我们这里的战利品表,他觉得我们这里掉三个太多了或者太少了怎么样的,它就可以在它的数据包里用同样的路径覆盖掉我的这个文件,然后把这个数字改成他的数字。这样的话他就只对我这个mod进行了一场修改,也不影响与其他mod的兼容性,也做到了自定义。本期教程要讲的就是这些。