本期教程我們來講一下如何修改戰利品表。首先,我們有一個需求,即添加一個兌換券,使得當我們使用帶有時運附魔的工具挖掘石頭時,可以掉落兌換券。
一個更符合原版的方法是在資源包中創建一個名為"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的兼容性,也做到了自定義。本期教程要講的就是這些。