提供: Minecraft Modding Wiki
このソースコードは、MinecraftForge 9.10.1.871にて作成されています。
1.6のカスタムツール追加
ここでは、以下の要素の実例サンプルを記載します。
ForgeOreDictionaryを利用したアイテムの取得が主ですが、類似の例として、FMLのGameRegistry.findItem(modid, name)を利用したアイテムの取得方法も合わせて記載します。
いずれの方法も、他MODへの改変や干渉なく、他MODのアイテムを取得して利用することが出来ます。
MOD作者によってはこれらの方法でアイテムを入手することを推奨し、APIでのアイテムへのアクセス手段を用意していない場合もあるので、他MODとの連携を考える場合に必要になるテクニックだと思います。
- 鉱石辞書への登録
- 既に登録されている鉱石辞書からItemStackを取得する
- FMLを利用し、modidとアイテム登録名からItemを取得する
ソースコード
- UseOreDicSample.java
package mods.tutorial.common; import java.io.IOException; import java.util.ArrayList; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.ShapedOreRecipe; import net.minecraftforge.oredict.ShapelessOreRecipe; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.EventHandler; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.registry.GameRegistry; /** * modid = このMODのIDです。他のMODと重複しない名前を心がけましょう * name = このMODの名前です。好きな名前をつけよう * version = これも任意でOK * dependencies = このMODが要求する・要求はしないが読み込み順を調整したいMODを記入します。 * "required"と入れると、そのMOD(ここでは9.10.~以降のForge、6.2.~以降のFML)が未導入だとクラッシュします。 * "after"はこのMODより後に読み込むことを意味します。連携先よりタイミングを遅らせたい場合に使用します。*/ @Mod( modid = "UseOreDicSample", name = "OreDictionarySampleMod", version = "1.6.2_1.0", dependencies = "required-after:Forge@[9.10,);required-after:FML@[6.2,)" ) public class UseOreDicSample { /**鉱石辞書から手に入れるアイテムの宣言です*/ public static ItemStack tinFromOreDic; /**鉱石辞書から手に入れるアイテムの宣言です。 * こちらはArrayListの形で取得しています。*/ public static ArrayList<ItemStack> listAllCoppers = new ArrayList<ItemStack>(); /**FMLのGameRegistry.findItemを利用して取得するアイテムです*/ public static ItemStack bronzeFromFML; @EventHandler public void preInit(FMLPreInitializationEvent event) { /**鉱石辞書への登録です。 * preInitで登録していますが、他のタイミングでも登録自体は可能です。 * ただし、自分がレシピに使いたいタイミングよりは先にしましょう。 * また、自作アイテムを登録したい場合は、自作アイテムの登録(Gameregistry.registerItem等)の後にします。*/ OreDictionary.registerOre("ingotIron", new ItemStack(Item.ingotIron, 1, 0)); } @EventHandler public void init(FMLInitializationEvent event) throws IOException { /**さっき登録したOreDictionaryを使用したレシピを登録します。*/ GameRegistry.addRecipe( new ShapedOreRecipe( new ItemStack(Item.bakedPotato, 1, 0), new Object[]{" X ","XYX"," X ", Character.valueOf('X'), "ingotIron", Character.valueOf('Y'), new ItemStack(Item.potato, 1, 0)})); GameRegistry.addRecipe( new ShapelessOreRecipe( new ItemStack(Item.beefRaw, 1, 0), new Object[]{ new ItemStack(Item.beefCooked, 1, 0), "ingotIron" })); } @EventHandler public void postInit(FMLPostInitializationEvent event) { /**その1:アイテム1つをOreDictionaryから取得する。 * この方法では、リストの先頭にあるアイテムを取得するので、どのMODのスズインゴットかは判別していない*/ /**Oredictionary.getOres(String)は、鉱石辞書名から登録済みアイテムのリストを取得するメソッド*/ ArrayList<ItemStack> tin = OreDictionary.getOres("ingotTin"); /**取得したArrayListが空でなければ、リスト先頭(0番目)のアイテムを取得する。*/ if (tin.size() > 0) { this.tinFromOreDic = new ItemStack(tin.get(0).getItem(), 1, tin.get(0).getItemDamage()); } /**スズインゴットの取得に成功した場合のみ実行される*/ if (this.tinFromOreDic != null) { GameRegistry.addRecipe( new ItemStack(Item.bucketEmpty, 1, 0), new Object[]{ " X ", "X X", Character.valueOf('X'), this.tinFromOreDic }); } /**その2:アイテムをArrayListの形で取得する。 * やっていることは、その1と実質的に変わっていない*/ this.listAllCoppers = OreDictionary.getOres("ingotCopper"); /**その3:鉱石辞書の利用ではないが、FMLのGameRegistry.findItemを使用した他MODのアイテム取得方法。 * ここでは、一例として架空のMODのアイテムを取得しています。 * 実際に使用する時は、使わせてもらいたいMODのID、アイテム登録名を調べて使いましょう。*/ /**注意として、ココで使用するアイテム名はunlocalizedNameや表示名ではなく、 * GameRegistry.registerItem(par1, par2)で登録した時の名前でなくてはいけません。 * 従って、RML利用MODなど、FML式の登録を行っていないMODのアイテムはこの方法では取得できません。 * また、Itemを取得するので、そのアイテムのメタデータは別途調べておく必要があります。*/ /**まずは、"hogehoge"というmodidのMODが読み込まれているかをチェック*/ if (Loader.isModLoaded("hogehoge")) { Item ret = GameRegistry.findItem("hogehoge", "hogeItem"); /**取得したアイテム(ret)が空でなかった場合、実行されます。*/ if (ret != null) { this.bronzeFromFML = new ItemStack(ret, 1, 0); if (this.bronzeFromFML != null) { GameRegistry.addRecipe( new ItemStack(Item.bucketEmpty, 1, 0), new Object[]{ " X ", "X X", Character.valueOf('X'), this.bronzeFromFML }); } } } } /**==========以下、当MODで追加される新規メソッド。別のクラスに分けても良い==========*/ /**別のクラスから、何らかのアイテムが銅インゴットとして鉱石辞書登録済みかを判定するためのメソッド * "ingotCopper"の登録リスト(うえのほうで取得したもの)に登録されていれば、trueが返ってくる*/ public static boolean isCopper(ItemStack itemstack) { boolean flag = false; flag = matchItems(listAllCoppers, itemstack); return flag; } /** * for文を回して、リストを順にチェックしている。 * isCopperメソッドでの判定に使う。 */ private static boolean matchItems(ArrayList<ItemStack> list, ItemStack items) { for (ItemStack checks : list) { if (checks != null && items != null && (items.itemID == checks.itemID && items.getItemDamage() == checks.getItemDamage())) { return true; } } return false; } /**あるアイテムに対して、鉱石辞書登録された名前を取得するメソッド。 * 注意として、この方法で取得できる鉱石辞書名は1つだけである点に注意。 * (複数の名前で登録されているアイテムの場合、NEIで確認した際に白字で表示される1つのみが有効。)*/ public static boolean isThisIngotSteel(ItemStack itemstack) { boolean flag = false; /**まずはitemstackの登録辞書名を取得 * 未登録の場合、thisNameには"Unknown"という文字列が返される*/ String thisName = OreDictionary.getOreName(OreDictionary.getOreID(itemstack)); /**取得した文字列が、"ingotSteel"に一致するか*/ flag = thisName.equalsIgnoreCase("ingotSteel"); return flag; } }
解説
OreDictionary.registerOre("ingotIron", new ItemStack(Item.ingotIron, 1, 0));
- "ingotIron" = 登録したい鉱石辞書名
- new ItemStack(Item.ingotIron, 1, 0) = 登録したいアイテムをItemStack型で登録します。
ArrayList<ItemStack> tin = OreDictionary.getOres("ingotTin");
- "ingotTin" = ここに欲しい鉱石辞書名を入れる
これにより、欲しい鉱石辞書名のアイテムをArrayList<ItemStack>型で取得することが出来ます。
注意点として、このメソッドを実行した時点で登録済みのものしか取得できないため、
実行をなるべく遅いタイミングにすることを推奨します。(ここではpostInitにて行っています。)
Item ret = GameRegistry.findItem("hogehoge", "hogeItem");
- "hogehoge" = ここでは架空のMODのmodidを使っています。実際は連携したいMODのIDを記載して下さい。
- "hogeItem" = 欲しいアイテムの「登録名」です。
登録名は、RML系のMODなど、Gameregistry.registerItem()を利用していない場合は存在しません。ご注意下さい。
また、Blockを取得する場合は.findBlock("modid", "name")という別のメソッドを使用する必要があります。
失敗するとエラーが発生するので、実際に使用する場合は、try・catchで囲うのが安全です。