読者です 読者をやめる 読者になる 読者になる

路地裏牧場

技術系ブログだったけどごった煮になった謎ブログ

羊でも分かるMinecraftForge 1.8 Modding アイテム追加

Java Minecraft Modding プログラミング

※2015/05/11 19:50 - モデルのパスが間違っていたのを修正しました。

※高度な知能を備えた羊を対象としています。
Modding wikiの内容を独自に噛み砕いて色々補完したものとなります。

前提環境

JDK6以上
IntelliJ IDEA
MinecraftForge 1.8-11.14.1.1402
Gradle 適当

環境を構築する

こちらの説明に従って環境を構築します(丸投げ)

コーディング(又の名をコピペ)

src/main/javaディレクトリに適当にパッケージを作り、そこにメインクラスを作ります。

StudyModdingCore.java

@Mod(modid = StudyModdingCore.MODID, name = StudyModdingCore.NAME, version = StudyModdingCore.VERSION)
public class StudyModdingCore {
    public static final String MODID = "studymodding";
    public static final String NAME = "StudyModding";
    public static final String VERSION = "1.0";

    public static SampleItem ITEM;

    public static final Logger LOGGER = LogManager.getLogger(NAME);

    @EventHandler
    public void preInit(final FMLPreInitializationEvent event) {
        ITEM = new SampleItem();
        GameRegistry.registerItem(ITEM, ITEM.getName());
    }

    @EventHandler
    public void init(final FMLInitializationEvent event) {
        if (event.getSide() == Side.CLIENT) {
            registerRenderer(ITEM_ICE_SWORD);
        }
    }

    private void registerRenderer(final NamedItem item) {
        final ModelResourceLocation location = new ModelResourceLocation(
                MODID + ":" + item.getName(), "inventory"
        );
        final RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
        renderItem.getItemModelMesher().register(item.getItem(), 0, location);
        info("Registered renderer: " + item.getName());

    }

    private void info(String msg) {
        LOGGER.info(msg);
    }
}

@ModアノテーションでMODのコアクラスであることを示します。これをつけるとForgeが探して各初期化メソッドを呼んでくれます。この例ではpreInit -> initの順に呼ばれます。

@Modに渡すパラメータはMODの識別子である重複不可のmodid以外は任意です。

特に機能を持たないアイテムのクラスSampleItemをpreInitで初期化して登録します。その後で呼ばれるinitで、呼び出し元がクライアントならレンダラー(描画うんちゃら)を登録します。
この例では名前とアイテムを持つNamedItemのインスタンスを受け取り、それを登録します。infoはただのログ出力です。

NamedItem.java

public interface NamedItem {
    public String getName();
    public Item getItem();
}

名前を持つアイテムであることを示すインターフェースです。
ItemFoodなどのクラスの継承に対応するためにこのような形にしています。

SampleItem.java

public class SampleItem extends Item implements NamedItem {

    private final String name = "sample_item";

    public ItemIceSword() {
        this.setCreativeTab(CreativeTabs.tabMaterial);
        this.setUnlocalizedName(StudyModdingCore.MODID + ":" + name);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public Item getItem() {
        return this;
    }
}

無機能アイテムクラスです。ItemクラスとNamedItemクラスを継承します。
クリエイティブモードの素材タブに登録して、未ローカライズ名を登録します。必ずmodidを前につけましょう。

リソースを準備する

アイテムアイコンに用いる16x16のpng画像を用意します。面倒な人は漢字アイコンとか使えばいいと思います。肉。
この画像ファイルの名前を、先ほどのアイテムのnameと同じにします。この例なら "sample_item.png"となります。これをsrc/main/resources/assets/studymodding/textures/itemsに配置します。studymoddingの部分はMODIDと同じにします。

次にモデルを定義するjsonファイルを作成します。今回は剣のモデルを流用します。以下の内容を同じく"sample_item.json"とし、src/main/resources/assets/studymodding/models/itemに配置します。
なお、テクスチャのフォルダ名は "items" となっていましたが、モデルは "item" になります。注意。

{
  "parent": "item/iron_sword",
  "textures": {
    "layer0": "studymodding:items/sample_item"
  }
}

parentは親のモデルです。普通のアイテムのモデルにしたい場合は"builtin/generated"を指定します。より細かく角度とかを指定することも出来ますが面倒なので省略します。バニラのjsonを見ながらコピペしたりするといいと思います。

実行

さていよいよ実行ですが、ここで注意。必ず、GradleタスクのrunClientから実行してください。IDEAプロジェクトに既に「Minecraft Client」とかいうのがありますがこれは罠です。いいですか、これは罠です。私はこれに騙されて1週間溶けました。
(他のIDEAに合わせたスマートな実行方法があるのかもしれないですが今のところはこれを使えば(私のハマった)罠は回避できます。)
runClientの実行はターミナルからでもいいですが、IDEAならGradleペインを開いてTasks/forgegradleにありますのでこれをダブルクリックすると実行されます。楽です。


おわり。