提供: Minecraft Modding Wiki
移動先: 案内検索

この記事は"Minecraft Forge"を前提MODとしています。

Stone pickaxe.png
中級者向けのチュートリアルです。


はじめに

IResourcePackインターフェースは、本来リソースパックのように機能する動的クラスを作成するためのものである。 この使い方次第で、ビルドパス(出力したMODのjarファイル)外にあるリソースを参照できるため、MODの利用者がリソースパックを使わずにリソースを変更することも可能。

以下は基本的にMinecraft 1.7.x/1.8を対象に解説する。1.8ではFML関連クラスのパッケージが変更となっているので、注意されたし。 なお、FML上には予めIResourcePackを実装したFileResourcePackやFolderResourcePack等のクラスが存在するが、ここでは扱わない。

ソースコード

package、import等は省略

SampleMod.java

@Modクラスでの書き方

@Mod(id="samplemod",name="samplemod")
public class SampleMod{

    /*略*/

    @EventHandler
    public void init(FMLInitializationEvent event){

        /*略*/

        //defaultResourcePacksはprivateのため、リフレクションが必要。
        //難読化名は1.7.10のもの。1.8では難読化されていない
        List<IResourcePack> defaultResourcePacks = ObfuscationReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "defaultResourcePacks", "field_110449_ao");
        defaultResourcePacks.add(new SampleResourcePack());

        /*略*/
    }

    /*略*/

}

SampleResourcePack.java

public class SampleResourcePack implements IResourcePack{
    public SampleResourcePack(){
        //コンストラクタは基本的に空で良い
    }

    @Override
    public InputStream getInputStream(ResourceLocation par1ResourceLocation) throws IOException {
        //参照されたリソースに対し、InputStreamを返す。
        return new FileInputStream(…
    }

    @Override
    public boolean resourceExists(ResourceLocation resource) {
        //参照されたリソースが存在するかの指定。
        return true;
    }

    @Override
    @SuppressWarnings("rawtypes")
    public Set getResourceDomains() {
        //IResourcePackが処理するリソースのドメインを指定。複数指定可能。
        return ImmutableSet.of("samplemod");
    }

    @Override
    public IMetadataSection getPackMetadata(IMetadataSerializer par1MetadataSerializer, String par2Str){
        //メタデータを持たせないならnullでよい
        return null;
    }

    @Override
    public BufferedImage getPackImage() {
        //パック画像も用意しないのであればnullでよい
        return null;
    }

    @Override
    public String getPackName() {
        //パックの名前。メタデータやパック画像を用意しないのであれば、プレイ中ユーザから見えることはない
        //空やnullを返すとクラッシュする
        return "SampleResourcePack";
    }

}

解説

リソースパックの登録

List<IResourcePack> defaultResourcePacks = ObfuscationReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "defaultResourcePacks", "field_110449_ao");
        defaultResourcePacks.add(new SampleResourcePack());

IResourcePackを実装したクラスを実際にリソースパックとして認識させるために、Minecraft.defaultResourcePacksフィールドを参照する。 privateのため、リフレクションを利用して取得する。

リソースの取得

@Override
    public InputStream getInputStream(ResourceLocation par1ResourceLocation) throws IOException {
        return new FileInputStream(…
    }
 
    @Override
    public boolean resourceExists(ResourceLocation resource) {
        return true;
    }

基本的にリソースはInputStreamで取得される。getInputStream(ResourceLocation)は、参照されたリソース(第1引数に渡されるResourceLocation)に対しInputStreamを取得させるための必須メソッド。 このメソッドで、FileInputStreamなり何なりを使用すれば、ビルドパスの外部にあるファイルをリソースとして取得させることが可能。

resourceExists(ResourceLocation)は、参照されたリソースがSampleResourcePackに存在するか(SampleResourcePackがリソースを返すか)を指定する必須メソッド。ビルドパスに用意したリソースを参照する場合は、falseを返せばよい。

例では簡略化してあるが、引数に渡されるResourceLocationをチェックして、適切な値を返すようにすること。 特にgetInputStreamでは、誤って存在しないファイルへのFileInputStreamを返すなどといったことが無いようにしたい。

後は、通常通りResourceLocationを使用するだけでよい。