• カテゴリー別アーカイブ Minecraft Modding
  • Minecraft » Minecraft Modding » Entity | Golemist
  • 【Minecraft Modding】1.18.1 環境構築

    こちらはPCゲーム「Minecraft」のMod作製の解説記事です。

    Minecraft.1.18.1、

    Forge-1.18.1-39.0.55での解説になります。

    ダウンロード

    Eclipse Foundation:Eclipse IDE

    Adoptium:OpenJDK

    MinecraftForge:Forge MDK

    はじめに

    Minecraft1.18.1でのMod作製を始めたので、これからMinecraftのMod作りに挑戦したい方の為に、Mod作製の環境構築の手順を説明していきます。筆者はJavaを専門で勉強したわけではなく、Minecraftのソースコードを見て使い方を覚えたので、環境構築に関する詳細は理解していません。あくまで私が環境構築をした方法を書くので、PC環境の違いなどによる差は分からないので、ご了承ください。

    環境構築に必要なツールとダウンロード

    MinecraftのMod作製を始める為に必要なツールとファイルをダウンロードします。英語のサイトなので画像を見ながらダウンロードを進めて下さい。

    Eclipse IDEのダウンロード

    EclipseのダウンロードはEclipse Foundation:Eclipse IDEで行います。ブラウザでアドレスを直接入力する場合は【eclipse.org】と入力して下さい。

    リンク先のページの右上にある【Download】をクリックして、次のページへ飛びます。

    上の画像のページに遷移したら、【Download x86_64】をクリックしてダウンロードを開始して下さい。

    JDKのダウンロード

    JDKのダウンロードはAdoptium:OpenJDKで行います。ブラウザでアドレスを直接入力する場合は【adoptium.net】と入力して下さい。

    上の画像で赤い円で囲んだ部分を確認してダウンロードしてください。

    Temurin 17 (LTS)

    ダウンロードは下の赤い円で囲まれた【Latest release】をクリックすると開始されます。

    MDKのダウンロード

    MDKのダウンロードはMinecraftForge:Forge MDKで行います。ブラウザでアドレスを直接入力する場合は【files.minecraftforge.net】と入力して下さい。

    上の画像の【MDK】をクリックして遷移する画面では、数秒待った後に、画面の右上に【SKIP】という赤い表示があるので、そこをクリックするとダウンロードが完了します。それ以外の表示は広告のようなので、用が無ければクリックしない事をオススメします。

    MinecraftForgeのアップデート状況によって、ダウンロードできるバージョンが変更されます。最初のページでは最新版のForgeが表示されるので、他のバージョンをダウンロードしたい場合は、左のリストから該当するバージョンを選択して、ページを切り替えて下さい。

    環境構築に必要な3つのファイル

    Eclipse、OpenJDK、MDKのダウンロードが完了したら、次はインストールを開始していきます。任意で上の画像の様にダウンロードを残しておくフォルダを作っても良いでしょう。もしくは、環境構築が完了したら削除しても良いので、一時的に見やすくする為に創るのもオススメです。

    JDKのインストール

    ダウンロードして【OpenJDK…】を起動してインストールを開始します。インストーラが起動したら、「次へ」をクリックします。

    【Set Java Home…】の設定

    次のページでは【Set Java HOME…】の設定を行います。上の画像の矢印の「Set JAVA HOME…」をクリックして「ローカルハードドライブにインストール」をクリックして下さい。詳しい方は自身の設定で行っても問題無いと思いますが、筆者の様に詳しくない人は、他の部分は変更しない方が良いと思います。

    設定が完了したら「次へ」をクリックして、インストールを完了させて下さい。

    Eclipseのインストール

    Eclipseのインストーラを起動すると、上の画像の画面が表示されるので、赤枠で囲んだ「Eclipse IDE for Java Developers」をクリックして下さい。

    次の画面は規約と同意のページなので、確認後に「Accept Now」をクリックして、更に次の画面に進みます。

    インストーラの参照を確認

    3つ目の画面ではEclipseが参照するフォルダを選択します。特に何もしなくても問題はないはずですが、環境に依っては参照先を変更する必要があるかも知れません。

    INSTALLをクリックしたら、インストールを開始します。

    Mod管理用のフォルダを作成

    Mod管理用のフォルダは詳しい人は、自由に行っても問題無いですが、分からない人はここで書かれている手順で作っていきましょう。

    まずはどこでもいいので、フォルダを作ります。上の画像のアドレスの「Golemist-1.18.1」のフォルダです。これは自分のMod名など、分かりやすい名前にしておきましょう。筆者はこれをデスクトップに置いています。

    筆者の場合は1.12.2でも開発を行っていたので、「Golemist」というフォルダの中で、1.12.2用のフォルダと1.18.1用のフォルダに分けています。

    今作ったフォルダ(筆者の環境では「Golemist-1.18.1」)の中に、2つのフォルダを作ります。筆者の場合は「Mod名」フォルダと「Mod名 + Workspace」フォルダです。ワークスペースフォルダはEclipseのワークスペースとして指定します(後述)。

    MDKをModフォルダに解凍

    MinecraftForgeでダウンロードしたMDKを先ほど作った「Mod名」フォルダ(Golemistフォルダ)に解凍する。誤ってワークスペース用のフォルダに解凍した場合は、移動して下さい。

    解凍が完了すると上の画像のようになります。フォルダのアドレスなども自身の設定と併せて確認して下さい。

    不要なファイルを削除

    この作業は行わなくても問題は無いです。開発やEclipseの起動に必要ない下記のものは削除しても大丈夫なので、任意で行ってください。
    ・changelog.txt
    ・CREDITS.txt
    ・LICENSE.txt
    ・README.txt

    changelog.txtやREADME.txtは、読める人には有用な情報が書かれているかも知れませんが、筆者は読めません。

    次はEclipseを起動して、ワークスペースを設定していきます。

    ワークスペースの設定

    Eclipseを起動すると、上の画像のウィンドウが表示されます。【Workspace:】のアドレス参照を、先ほど作成したワークスペース用のフォルダに変更します。ウィンドウ中央左の「Use this as the default and do not ask again」のチェックは、Eclipseを起動するたびに、ワークスペースの選択をするかどうかの設定で、チェックを入れると、次回からはこのウィンドウが表示されなくなります。複数のプロジェクトを作っている場合に、起動時に選択したい場合はチェックを入れない方が楽かも知れません。作るModが一つの場合や、Eclipseの作業画面上でのワークスペースの切り替え方法を知っている人は、チェックを入れても良いと思います。

    ワークスペースの設定が完了したら右下の「Launch」をクリックして起動しましょう。

    初回起動時の表示を閉じる

    Eclipse上で初めて起動したワークスペースでは、上の画像の画面が表示されます。見る必要が無い人は、画面左上の✖でタブを閉じましょう。

    ファイルのインポート

    Eclipseが起動したら、この画面になります。

    初めにMDKをインポートする為に、上の画像の赤枠で囲んだ「Import project」をクリックして下さい。

    インポートの選択

    インポートをクリックして表示されたウィンドウでは、「Gradle」ファイル内の「Existing Gradle Project」(日本語表記は「既存のGradleプロジェクト」)を選択し、ウィンドウ下の「Next」をクリックします。

    インポートの参照フォルダ

    次の画面ではインポート先の設定を行います。ワークスペースと一緒に作製して、MDKを解凍したフォルダ(Mod名フォルダ)を参照します。

    参照の設定が完了したらウィンドウ下の「Finish」をクリックしてインポートを開始します。インポートには自信の環境に応じた時間が掛かります。インポートが完了するとEclipseの作業ウィンドウの左側に、「Mod名」のファイルが表示されます。

    その他の作業

    build.gradleファイルの書き換え

    インポートが完了した後に表示される「Mod名」のファイルの左の「>」をクリックすると、ファイルの中身が表示されます。この中にある「build.gradle」の内容を書き換えていきます。

    16行目のversion情報は、Modのバージョンを表します。特に何も無ければ「1.0」のままで良いと思います。

    17行目のgroupは製作者の名前です。「com. 名前 .mod名」にしている人もいますが、筆者の場合はcom.は書いていません(lily_yuri.golemist)。すべて半角アルファベットの小文字で記入して下さい。記号は一部しか使用できないので、注意が必要です。

    18行目はmodidを入れます。こちらも半角アルファベットの小文字で入力して下さい。

    59、81、106行目では、「examplemod」と書かれた部分を18行目に書いたmodidで上書きして下さい。

    150行目の”Specification-Title”の右側の「examplemod」の部分を自身のMod名に書き換えて下さい。筆者の場合は「Golemist」。ここでは大文字が使用できるようです。

    151、155行目の「examplemodsareus」の部分を、作者の名前に書き換えて下さい。筆者の場合は「lily_yuri」。

    【genEclipseRuns】を起動

    build.gradleの書き換えが完了したら、Eclipseのウィンドウ右下の【Gradle Tasks】タブ内の、Mod名のファイルを開くと、中に「forgegradle runs」というフォルダがあり、その中に「genEclipseRuns」という項目があるので、ダブルクリックで起動します。

    これは少し時間が掛かるようです。

    【eclipse】を起動

    「genEclipseRuns」を起動するとタブが「Gradle Executions」に切り替わるので、「Gradle Tasks」をクリックしてタブを戻します。先ほどの「forgegradle runs」フォルダの少し下に「ide」というフォルダがあります。その中の「eclipse」をクリックして起動します。これはすぐに終わります。

    パッケージの再読み込み

    先ほどの「eclipse」のクリックの後に、ウィンドウ左上のModフォルダをクリックしてから、キーボードの「F5」を押して、プロジェクトを更新します。

    更新が完了すると、上の画像の様に、ファイルなどが表示されます。

    不要なフォルダの削除

    src/main/java内の「com.example.examplemod」は不要なので、削除します。筆者は中身を見ていませんが、Mod作製の為の基礎が書かれていたかも知れません。気になる方は削除する前に見てみると良いでしょう。

    Main.Javaクラスを作成

    最後に、Main.Javaクラスを作成します。

    src/main/javaを右クリックして、「new」の項から「Package」をクリックして新しいパッケージを作ります。パッケージ名はbuild.gradle内の17行目のgroupに記述したものを書きます。筆者の場合は「lily_yuri.golemist」がパッケージ名です。

    パッケージを作成したら、それを右クリックして「new」の項からClassをクリックして、クラスを作成します。クラス名はMod名にする人と、「Main.Java」にする人に分かれますが、MinecraftのModをほとんどは「Mod名.Java」になっているので、筆者は「Golemist(Mod名)」にしています。

    クラスの作製を始めたら、下記のコードと同じように記述してみて下さい。”golemist”の部分は小文字でModidを、クラス名は自身が付けたクラス名になります。「public Golemist」(コンストラクタ)の部分も同様に自身が付けたクラス名になります。

    @Mod("golemist")
    public class Golemist {
    
    	public Golemist() {
    		MinecraftForge.EVENT_BUS.register(this);
    	}	
    }

    Main.Javaのクラスの記述が終わったら、Eclipseの作業画面の上の(左の)をクリックしてMinecraftを起動してみましょう。問題が無ければMinecraftが起動し、Modの画面に自分のModが並んでいるはずです。

    MineCraft 目次に戻る
  • Minecraft-1.15.2 Mod開発 Itemの追加

    こちらはPCゲーム「Minecraft」のMod作製の解説記事です。

    Minecraft.1.12.2、

    Forge-1.12.2-14.23.2.2611での解説になります。








    ここではMinecraft-1.15.2のMod開発での「アイテムの追加」の方法を解説します。

    この記事を書いている私自身が元々はJavaを勉強したことが無い状態からMod作製を始めたので、説明内容などはプロのプログラマーの人が見たら「既に知っている」事や「当たり前」の事などもあると思います。この記事は私の様にJavaに初めて触れる人や、これからMod作製に挑戦したい人やMod作製の初心者の人の為に書いているものなので、専門用語を使う時と使わない時があります。また、記載内容に誤りや私自身の理解が誤っている可能性がある事をご了承ください。

    アイテムの追加

    アイテム登録用のクラスを作る

    アイテムを追加する為に必要なレジストリ登録用のクラスを作成する。効果の無いアイテム(素材用)の追加だけなら、このクラスだけで完結させる事も出来る。

    
    @Mod.EventBusSubscriber(modid = Golemist.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)
    public final class GolemistItems {
    
    	public static final Item PUMPKIN_ROD = registerItem(new PumpkinRodItem(noStackNoDurability(new Item.Properties())),
    			LibraryItemNames.PUMPKIN_ROD);
    
    
    	public static final ToolBase WOODEN_STICK = registerItem(new ToolBase(setDefault(new Item.Properties()),
    			GolemItemTier.WOOD,
    			ToolType.STICK),
    			LibraryItemNames.WOODEN_STICK);
    
    	public static final Item TEST_ITEM = new Item(setDefault(new Item.Properties())).setRegistryName("test_item");
    
        private static <T extends Item> T registerItem(T item, String name) {
        	item.setRegistryName(name);
            return item;
        }
    
        private static Item.Properties setDefault(Item.Properties properties) {
        	properties.group(Golemist.CREATIVE_TAB);
        	return properties;
        }
    
        private static Item.Properties noStackNoDurability(Item.Properties properties) {
        	properties.maxStackSize(1);
        	return setDefault(properties);
        }
    
        private static Item.Properties setStackSize(Item.Properties properties, int size) {
        	properties.maxStackSize(size);
        	return setDefault(properties);
        }
    
    
    	@SubscribeEvent
    	public static void registerItems(RegistryEvent.Register<Item> event) {
            try {
                for (Field field : GolemistItems.class.getDeclaredFields()) {
                    Object obj = field.get(null);
                    if (obj instanceof Item && ((Item) obj).getRegistryName() != null) {
                    	event.getRegistry().register((Item) obj);
                    }
                    else if (obj instanceof Item[]) {
                        for (Item item : (Item[]) obj) {
                            event.getRegistry().register((item));
                        }
                    }
                }
            } catch (IllegalAccessException exception) {
                throw new RuntimeException(exception);
            }
    	}
    }

    上に載せたコードが私が自作しているModでのアイテム登録用クラスで、見やすくするために他のアイテムの登録は消してある。

    クラスの初めに記述している「public static final Item PUMPKIN_ROD =」が登録したいアイテムの登録内容を作成している。newでアイテムのインスタンスを生成し、その中でItem.Propertiesのインスタンスを生成し、アイテムの登録名とを引数として「registerItem」という同クラス内のメソッドに渡す。「registerItem」に渡す「Item.Properties」の設定に同クラス内のメソッド「noStackNoDurability」を使用している。

    この「noStackNoDurability」と他の2つ「setStackSize」「setDefault」を使い分けてプロパティを設定している。Item.Propertiesの設定はそれぞれのアイテムクラスのコンストラクタで個別に設定する事も可能だが、私の場合はレジストリ登録をするこのクラスで他のアイテムと比較をし易くする為や、プロパティの設定漏れを防ぐ目的でここで設定する事にしている。
    setDefault(Modのクリエイティブタブへの登録のみ)
    noStackNoDurability(setDefault + 耐久値無しのスタック数1)
    setStackSize(setDefault + スタック数の設定

    「public static final ToolBase WOODEN_STICK =」はツールの登録で、ここで詳しくは書かないが、コンストラクタでツールの素材とツールのタイプを設定するだけで、攻撃力、採掘速度、耐久値などのツールに必要なプロパティが設定されるようにしてある。このクラスの解説は別の記事に記載する予定。Javaに慣れている人でツールを作りたい人は「Items」クラスのレジストリ登録の記述で「SwordItem」などの部分を見ると分かるかも知れない。

    ツールの登録の部分を消さずに記載したのは、私のようにJavaを勉強中の人が登録の方法を自身の好みや目的にあったものを見つけられたらと思ったから。

    それぞれのアイテムクラス内のコンストラクタでItem.Propertiesのインスタンスを生成するメリットと思ったのはレジストリ登録クラスでの記述が減るので、登録の記述が見易くなる。新しく作ったアイテムクラスをレジストリ登録をする際にもコピペで済むものが多くなると思う。

    私のModの場合はゴーレム用の装備やツールなどの通常のアイテムとは違い攻撃力や耐久値などを持つアイテムの追加があり、それの攻撃力などは個別設定では無く、ツールの素材やツールのタイプで自動的に計算されるようにコンストラクタで記述している為、レジストリ登録クラスでItem.Propertiesのインスタンスを生成している。他にもルーン文字などの追加も行うので、個別のアイテムクラスでは無くツール類のように、1つのクラスでプロパティの内容の違った複数のアイテムを作成するので、上記の方法を選択した。また、何の効果も持たないレシピ用の素材アイテムなどを登録するする際にsetDefault()などのメソッドを使用する事で、登録の記述量は少なくて済む。そういったアイテムは個別のクラスを作る必要も無いので、メソッドを使いまわしやすい。3つ目の記述「public static final Item TEST_ITEM = 」がそれである。

    アイテムの登録名を設定する際に呼び出している「LibraryItemNames」クラスはアイテムの登録名を定数で記述したクラスで、記述ミスを防ぐ為に使用している。なので、そういったものが不要な人は”アイテム名”で記述しても問題は無い。ちなみに「LibraryItemNames」での記述は、
    public static final String PUMPKIN_ROD = “pumpkin_rod”;

    「public static void registerItems」ではこのクラス内のフィールド(登録するアイテム)の数だけfor文で登録を繰り返すメソッドである。メソッドの注釈に「@SubscribeEvent 」を記述している事と、クラスの注釈に「@Mod.EventBusSubscriber(modid = Golemist.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD)」を記述すると、Modの読み込み時に自動的に呼び出してくれるので、他のクラスなどからレジストリ登録メソッドを呼び出さなくても良くなる。

    後はアイテムを描画するモデルとテクスチャを用意するだけで単純なアイテムは完成となる。

    モデルはsrc/main/resources/assets/ModのID/models/item内で、テクスチャは「src/main/resources/assets/ModのID/textures/item」に入れる必要がある。用意したテクスチャをそのまま描画するだけのアイテムであれば、Minecraft本体のmodelのjsonファイルをコピーして、ファイル名や記述内のテクスチャ名をなどの参照を書き換えるだけで良い。

    ※アイテムクラスでの記述などは少しずつ追記していく予定ですが、「こういった部分を知りたい」などの要望があれば、優先して追記したいと思っています。私が理解して説明できるようになっている部分に限定されますが、気になる方はコメントにて要望や質問をして頂ければと思います。

    MineCraft 目次に戻る
  • Minecraft-1.15.2 Mod開発

    こちらはPCゲーム「Minecraft」のMod作製の解説記事です。

    Minecraft.1.12.2、

    Forge-1.12.2-14.23.2.2611での解説になります。








    Minecraftの世界に存在する動物やモンスターなどのMob。これらに加え弓から放たれた矢、ブレイズの火球などがEntityに含まれます。

    ここではMinecraft-1.15.2でのMod開発の際に私が理解できたメソッドなどを自分用のメモも兼ねて載せていきたいと思います。他にも1.12.2から1.15.2で名称が変わったクラスなども載せていく予定です。

    この記事を書いている私自身が元々はJavaを勉強したことが無い状態からMod作製を始めたので、説明内容などはプロのプログラマーの人が見たら「既に知っている」事や「当たり前」の事などもあると思います。この記事は私の様にJavaに初めて触れる人や、これからMod作製に挑戦したい人やMod作製の初心者の人の為に書いているものなので、専門用語を使う時と使わない時があります。また、記載内容に誤りや私自身の理解が誤っている可能性がある事をご了承ください。

    記事の内容は徐々に追加していく予定です。

    1.12.2からの変更

    ブロックへのTileEntityの実装について

    TileEntityをBlockに実装する際の注意として、かまどのクラスの元になるクラス「AbstractFurnaceBlock」などが継承している「ContainerBlock」というクラスがある。このクラスを継承して作ったブロックの場合、ContainerBlock自体がITileEntityProviderというインタフェースをimplementsしているので、
    createNewTileEntity(IBlockReader worldIn);
    というメソッドを実装するようになっているが、@Deprecatedの注釈がついているので、使用しない方が良い。注釈へのコメントにも「使用しないでください。」とあり、代わりにBlockクラスが継承しているIForgeBlockというインタフェースに、
    createTileEntity(BlockState state, IBlockReader world)
    こちらを使用するようにと記載されている。他のModのソースを参考にしようとした際に、ContainerBlockを継承して作られた追加Blockクラスの記述にはcreateNewTileEntityを使用しているものがあるので、コピーして使用する際はcreateTileEntityに直した方が良いと思われる。

    ContainerBlockを継承していない追加Blockクラスの場合は、ITileEntityProviderimplementsしていないので、createTileEntityを使用する事になるので間違える事は無いと思われる。

    同時にIForgeBlockhasTileEntity(BlockState state)のdefaultの記述が、
    default boolean hasTileEntity(BlockState state) {
    return this instanceof ITileEntityProvider;
    }
    となっているので、TileEntityを実装するクラス内でhasTileEntityをオーバーライドしておいた方が良い(特にITileEntityProviderを実装していないクラス)。クラスごとにオーバーライドする場合は、TileEntityを実装した事の確認が確実なら、return ture;で問題は無い。

    ブロッククラス内のメソッド

    TileEntityを持ったBlockクラスの記述で、onBlockActivatedの戻り値がbooleanからActionResultTypeに変更になり、引数も以下の表の通りに変更されている。

    1.12.2 1.15.2
    World world BlockState state
    BlockPos pos World world
    IBlockState state BlockPos pos
    EntityPlayer player PlayerEntity player
    EnumHand hand Hand hand
    EnumFacing side BlockRayTraceResult hit
    float hitX
    float hitY
    float hitZ

    クラス

    クラス名称の「Entity◯◯」が「◯◯Entity」に変更されている。AIクラスの名称も「AI○○」から「○○Goal」に変更されている。

    1.12.2のクラス名称 1.15.2のクラス名称
    Entity Entity
    EntityLivingBase LivingEntity
    EntityLiving MobEntity
    EntityMob MonsterEntity
    AI◯◯ ◯◯Goal

    メソッド

    1.12.2のメソッド名称 1.15.2のメソッド名称
    getLookHelper() getLookController()
    updateTask() tick()

    ItemのProperty(Item.Properties)

    アイテムをレジストリに登録する際に使用するEntityなどの登録の際に使用するBuilderクラスと同じような使い方をするクラスで、アイテムのスタック数や耐久値などの設定を追加するクラス。

    public static final Item PUMPKIN_ROD = registerItem(new PumpkinRodItem(noStackNoDurability(new Item.Properties())),
    			LibraryItemNames.PUMPKIN_ROD);
    
        private static <T extends Item> T registerItem(T item, String name) {
        	item.setRegistryName(name);
            return item;
        }
    
        private static Item.Properties setDefault(Item.Properties properties) {
        	properties.group(Golemist.CREATIVE_TAB);
        	return properties;
        }
    
        private static Item.Properties noStackNoDurability(Item.Properties properties) {
        	properties.maxStackSize(1);
        	return setDefault(properties);
        }
    
        private static Item.Properties setStackSize(Item.Properties properties, int size) {
        	properties.maxStackSize(size);
        	return setDefault(properties);
        }

    上に載せたコードは私が自作しているModのGolemistのMinecraft-1.15.2版のアイテムの登録のクラスの一部で、registerItemという同クラス内のメソッドにItem.Propertiesの登録内容と登録名を渡している。引数に渡すItem.Propertiesを同クラス内のメソッドnoStackNoDurabilityにインスタンスを生成して渡し、その中でプロパティを設定している。noStackNoDurabilityは最大スタック数を1に設定した後にsetDefaultメソッドに渡す。setDefaultは単純にアイテムのクリエイティブタブを設定するだけなので、クリエイティブタブの設定のみのアイテムはsetDefaultを使用している。スタック数を設定したアイテムはsetStackSizeメソッドを使用している。

    私がレジストリ登録用のクラスでプロパティを生成している理由は、後で他のアイテムと値を比較しやすくする為なので、それが必要無い場合は個別のクラスの中でプロパティを設定しても良いと思う。更に見やすくするのなら、別クラスとしてプロパティを見易く記述したライブラリの様な参照用のクラスを作っても良いかも知れない。

    1.12.2ではアイテムのクラス内でスタック数や耐久値を入力していたが、1.1.52での他の人が書いたModソースを見ているとItem.Propertiesを使用して、レジストリ登録の方で記述が多い印象を受ける。各アイテムクラス内で個別に設定しても問題は無いので、どちらで設定するかは作者の好みになる。

    Item.Propertiesの登録内容の中から私が使用できるようになったものの説明を記載していく。

    maxStackSIze(int maxStackSizeIn)
    名前の通りアイテムのスタック数を設定するメソッドで、引数に渡した値がそのまま最大スタック数となる。この時、そのアイテムの耐久値が設定されていた場合は例外処理でエラーログを出す。

    defaultMaxDamage(int maxDamageIn)
    アイテムの耐久値を設定するメソッドで、引数に渡した値を耐久値に設定すると同時に最大スタック数を1に設定する。なので、耐久値を設定する場合は上記のmaxStackSIzeのメソッドを使用しなくても良い。

    group(ItemGroup groupIn)
    そのアイテムをクリエイティブタブのどこのカテゴリに登録するかを決めるメソッドで、自身のMod専用のクリエイティブタブに登録する事も出来る。

    setNoRepair()
    名前の通りで、これを使用したアイテムは修理が出来なくなる。耐久値が無いアイテムには関係ないので設定しても意味がない。

    MineCraft 目次に戻る
  • Minecraft1.12.2でMod作製 Entity

    こちらはPCゲーム「Minecraft」のMod作製の解説記事です。

    Minecraft.1.12.2、

    Forge-1.12.2-14.23.2.2611での解説になります。








    Minecraftの世界に存在する動物やモンスターなどのMob。これらに加え弓から放たれた矢、ブレイズの火球などがEntityに含まれます。

    ここでは「Entity」クラスに含まれる生物に関するクラス「EntityLivingBase」の型階層やEntityを作製する際に使う可能性の高い処理などのEntityの作製に関する情報を載せています。この記事を書いている私自身が元々はJavaを勉強したことが無い状態からMod作製を始めたので、説明内容などはプロのプログラマーの人が見たら「既に知っている」事や「当たり前」の事などもあると思います。この記事は私の様にJavaに初めて触れる人や、これからMod作製に挑戦したい人やMod作製の初心者の人の為に書いているものなので、専門用語を使う時と使わない時があります。また、記載内容に誤りや私自身の理解が誤っている可能性がある事をご了承ください。

    記事の内容は徐々に追加していく予定です。

    EntityLivingBase

    型階層

    EntityLivingBaseからの型階層。eclipseでは型階層は対象のクラスを指定して右クリックで表示されるメニューから「型階層を開く」もしくはクラスを指定した状態で「F4」キーを押す事で確認出来る。eclipseで簡単に確認できるので、クラス継承などの確認だけであればeclipseの方が早いかも知れない。

    EntityLivingBaseの型階層

    EntityLivingBase EntityArmorStand
    EntityLiving
    EntityPlayer

    EntityLivingBaseは上の表のように3つに分かれ、生物に関するメソッドや変数などが記載されている。アーマースタンドは体力も無く、生物とは言えないかもしれないが、内部的にはEntityLivingBaseの型階層に含まれる。これはアーマースタンドがプレイヤーと同様に鎧などの装備品に関わる「handInventory」と「armorArray」を実装しているからである。それ以外はプレイヤーかプレイヤー以外の生物かで2つのクラスに分かれる。

    EntityLivingの型階層

    EntityLiving EntityAmbientCreature EntityBat
    EntityCreature
    EntityDragon
    EntityFlying EntityGhast
    EntitySlime EntityMagmaCube
    EntityWaterMob EntitySquid

    EntityLivingからは上の表にように分かれる。EntityFlyingにはガストのみが含まれ、ブレイズなどはEntityCreatureの先のEntityMob(敵対的な生物)に含まれる。スライムも敵対的な生物ではあるが他のMobと実装している内容が違うので分かれている。スライム、ガスト、シュルカー、エンダードラゴンはインターフェースの「IMob」を実装している為、「これらを含む敵対的な生物」を取得する時は「IMob」を使用すると良い。
    例:if文
    if (this.getAttackTarget instanceof IMob)

    ほとんどの生物はEntityLivingの先のEntityCreatureに含まれるので、型階層から探す場合はEntityCreatureから探すと良い。

    EntityCreatureの型階層

    EntityCreature EntityAgeable
    EntityGolem
    EntityMob

    EntityCreatureからは上の3つに分かれる。EntityAgeableからは動物と村人に、EntityGolemからはアイアンゴーレムとスノーゴーレムとシュルカー、EntityMobからは殆どの敵対的な生物に分かれる。

    EntityAgeable ➡ EntityAnimalの型階層

    EntityAnimal AbstractHorse
    EntityChicken
    EntityCow
    EntityPig
    EntityPolarBear
    EntityRabbit
    EntitySheep
    EntityTameable

    EntityAnimalからは上の表のように分かれる。EntityTameableには馬、ロバ、ラバ、ラマを除く「手懐け可能な動物」のオオカミ、ヤマネコ(ネコ)、オウムが含まれる。

    よく使用されるメソッド

    Entityを右クリックした時

    public boolean processInteract(EntityPlayer player, EnumHand hand)

    EntityLivingクラスのprocessInitialInteract内で呼び出される。processInitialInteractはEntityを右クリックした際の処理で、Entityクラスで実装されているが処理内容はfalseを返すのみで実際にはEntityLiving内でオーバーライドされ処理内容が実装されている。初めにEntityへのリードの付け外しの処理を実行するかの判定が行われ、それが行われなかった場合に、processInteractの処理が実行される。processInitialInteractはfinalの修飾子が付いているのでオーバーライドが出来ない。その為、「プレイヤーがリードを持っている」状態か、「Entityにリードが付いている」状態を条件とする処理は実装できない事になる。

    processInteractの処理の流れは、継承先のクラスでの(右クリックした時の)処理内容の判定を行ってから、処理が行われずに最後までいった時には継承元のprocessInteractが実行される。以下はEntityWolf(オオカミ)クラス内の「processInteract」。

        public boolean processInteract(EntityPlayer player, EnumHand hand)
        {
            ItemStack itemstack = player.getHeldItem(hand);
    
            if (this.isTamed())
            {
                if (!itemstack.isEmpty())
                {
                    if (itemstack.getItem() instanceof ItemFood)
                    {
                        ItemFood itemfood = (ItemFood)itemstack.getItem();
    
                        if (itemfood.isWolfsFavoriteMeat() && ((Float)this.dataManager.get(DATA_HEALTH_ID)).floatValue() < 20.0F)
                        {
                            if (!player.capabilities.isCreativeMode)
                            {
                                itemstack.shrink(1);
                            }
    
                            this.heal((float)itemfood.getHealAmount(itemstack));
                            return true;
                        }
                    }
                    else if (itemstack.getItem() == Items.DYE)
                    {
                        EnumDyeColor enumdyecolor = EnumDyeColor.byDyeDamage(itemstack.getMetadata());
    
                        if (enumdyecolor != this.getCollarColor())
                        {
                            this.setCollarColor(enumdyecolor);
    
                            if (!player.capabilities.isCreativeMode)
                            {
                                itemstack.shrink(1);
                            }
    
                            return true;
                        }
                    }
                }
    
                if (this.isOwner(player) && !this.world.isRemote && !this.isBreedingItem(itemstack))
                {
                    this.aiSit.setSitting(!this.isSitting());
                    this.isJumping = false;
                    this.navigator.clearPath();
                    this.setAttackTarget((EntityLivingBase)null);
                }
            }
            else if (itemstack.getItem() == Items.BONE && !this.isAngry())
            {
                if (!player.capabilities.isCreativeMode)
                {
                    itemstack.shrink(1);
                }
    
                if (!this.world.isRemote)
                {
                    if (this.rand.nextInt(3) == 0 && !net.minecraftforge.event.ForgeEventFactory.onAnimalTame(this, player))
                    {
                        this.setTamedBy(player);
                        this.navigator.clearPath();
                        this.setAttackTarget((EntityLivingBase)null);
                        this.aiSit.setSitting(true);
                        this.setHealth(20.0F);
                        this.playTameEffect(true);
                        this.world.setEntityState(this, (byte)7);
                    }
                    else
                    {
                        this.playTameEffect(false);
                        this.world.setEntityState(this, (byte)6);
                    }
                }
    
                return true;
            }
    
            return super.processInteract(player, hand);
        }

    上のコードの最後にある「return super.processInteract(player, hand);」で継承元(親クラス)のprocessInteractを呼び出している。このコード(EntityWolfの)をコピーして間の処理内容を自分の作りたい処理に書き換えれば、右クリックした時の処理が実装または変更が出来る。

    継承先のクラスの処理を先に判定する場合

        public boolean processInteract(EntityPlayer player, EnumHand hand)
        {
    
        	//ここに処理内容を記述
        	//処理が実行される場合はreturn true;を記述
    
            return super.processInteract(player, hand);
        }

    親クラスの処理を先に判定する場合

    public boolean processInteract(EntityPlayer player, EnumHand hand)
    {
        if (super.processInteract(player, hand))
        {
            return true;
        }
    
        //ここに処理内容を記述
        //処理が実行される場合はreturn true;を記述
    
        return false;
    }

    processInteractは戻り値がboolanなので、当然ながらtrueかfalseを返す必要がある。オリジナルで作った処理が実行された後にreturn (true)を記述しておかないと、「継承先の処理を優先する場合」は継承元(親クラス)の処理も実行されてしまい、「継承元の処理を優先する場合」はプレイヤーが手にアイテムを持っていた場合は、そのアイテムを右クリックで使用した際の処理も実行されてしまう。

    EntityWolfクラスのprocessInteractの
    ItemStack itemstack = player.getHeldItem(hand);
    ここに記載されている引数handは「プレイヤーが手に持っているアイテム」なので、どちらの手に持っているかは関係しない。なので、持っている手を指定したい場合は・・・
    player.getHeldItemMainhand();メインハンド
    player.getHeldItemOffhand();オフハンド
    に変更すれば良い。

    EntityのAI

    EntityAIBase

    Entityの行動を決定するAIクラスの元となるabstractクラスで、バニラのEntityAIはこれを継承して作成されている。なのでオリジナルのAIを作る場合も、これを継承したAIクラスを作ってEntityクラスで使用する事になる。
    ※abstractクラスは抽象クラスと呼ばれ、継承して使用する為のクラス。これを継承したクラスは、必要なメソッドの実装がされていないと、エラーを出してくれるので、「必要なメソッドの実装漏れが起きない」と、ここでは思って欲しい(詳しい説明は省くため)。

    実際に動作する時のAIの流れは、
    ・shouldExecute():AIの起動条件をここで記述する
    ・shouldContinueExecuting():AIの継続条件をここで記述する
    ・isInterruptible():このAIより優先度(Priority)の高いAIが起動する時に、このAIを止めて起動させられるかどうか(バニラのAIはすべてtrue)
    ・startExecuting():AIが起動する時に呼び出される処理
    ・resetTask():AIが中断された時に呼び出される処理
    ・updateTask():AIが起動してから継続している間に断続的に呼び出される処理
    ・setMutexBits(int mutexBitsIn):同時に動作できる他のAIとの競合をビット演算子で設定する
    ・getMutexBits():mutexBitsの値を取得

    package net.minecraft.entity.ai;
    
    public abstract class EntityAIBase
    {
        /**
         * A bitmask telling which other tasks may not run concurrently. The test is a simple bitwise AND - if it yields
         * zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
         */
        private int mutexBits;
    
        /**
         * Returns whether the EntityAIBase should begin execution.
         */
        public abstract boolean shouldExecute();
    
        /**
         * Returns whether an in-progress EntityAIBase should continue executing
         */
        public boolean shouldContinueExecuting()
        {
            return this.shouldExecute();
        }
    
        /**
         * Determine if this AI Task is interruptible by a higher (= lower value) priority task. All vanilla AITask have
         * this value set to true.
         */
        public boolean isInterruptible()
        {
            return true;
        }
    
        /**
         * Execute a one shot task or start executing a continuous task
         */
        public void startExecuting()
        {
        }
    
        /**
         * Reset the task's internal state. Called when this task is interrupted by another one
         */
        public void resetTask()
        {
        }
    
        /**
         * Keep ticking a continuous task that has already been started
         */
        public void updateTask()
        {
        }
    
        /**
         * Sets the mutex bitflags, see getMutexBits. Flag 1 for motion, flag 2 for look/head movement, flag 4 for
         * swimming/misc. Flags can be OR'ed.
         */
        public void setMutexBits(int mutexBitsIn)
        {
            this.mutexBits = mutexBitsIn;
        }
    
        /**
         * Get what actions this task will take that may potentially conflict with other tasks. The test is a simple bitwise
         * AND - if it yields zero, the two tasks may run concurrently, if not - they must run exclusively from each other.
         * See setMutextBits.
         */
        public int getMutexBits()
        {
            return this.mutexBits;
        }
    }

    各メソッドの動作は、
    shouldExecute()
    AIの起動条件でtrueの場合、このAIが起動する。例えば体力が0になって死亡処理中(赤くなって倒れてから消える)のMobに近寄っても攻撃されないようにするなど。

    shouldContinueExecuting()
    AIの継続条件でtrueの場合はAIを継続。falseの場合はAIがresetTask()が呼び出される。例えば攻撃対象が何らかの理由で居なくなった時など。

    isInterruptible()
    バニラのAIはすべてtureを返すので、Entityクラスで実装する時に設定するPriorityの値で優先度が決まる。オリジナルのAIで継続中に他のAIに割り込ませたくない場合はfalseを返す様にするか、返す条件を記述すれば良い。

    startExecuting()
    AIが起動する時に呼び出される処理。抽象メソッドではないので、実装しなくても良い。攻撃対象を決定するAIでshouldExecute()で対象に対しての正負を設定して、trueの場合にはEntityのattackTargetに対象のEntityを設定するなど、オオカミが周囲の羊を攻撃する時のターゲット用のAIで使用されている。

    resetTask()
    AIが中断された時に呼び出される処理で、抽象メソッドではないので、実装しなくても良い。shouldContinueExecuting()がfalseの時に呼び出される。EntityAIAttackMeleeなどで攻撃後に対象が死亡した場合や、オオカミなどが戦闘中にプレイヤーによる待機命令を受けた時などに、attackTargetを初期化するなど。

    updateTask()
    AIが起動してから継続している間に断続的に呼び出される処理でEntityAIAttackMeleeなどでは、攻撃対象との距離に応じて移動の目的地の再設定までの期間を設定したり、攻撃の届く距離まで近付いた場合に、近接攻撃のメソッドを呼び出す(attackEntityAsMob)。

    setMutexBits(int mutexBitsIn)
    同時に動作できる他のAIとの競合をビット演算子で設定する。他のAIを見るとわかるようにコンストラクタの中に必要に応じて設定する。shouldExecutingで複数のAIがtrueを返した場合で、それらのAIの中で、このAIクラスよりPriorityが低いAIの同時実行を許すかを決定する。ビット演算の知識が無いと設定を理解するのが難しいので、それらを解説しているサイトを見るか、既存のAIクラス同士を見て比べたり、設定してみてテストする事になるが、後者の場合はエラーの確認をしっかりと行う必要がある。

    メソッドの説明にもある通り、
    ・1 = motion:移動
    ・2 = look/head motion:頭の動き
    ・4 = swim:泳ぐ

    例えばEntityAIAttackMeleeクラスは値が3なので1~5の中では1、2、3、5とANDになるので、他のAIでこのAIよりPriorityが低いAIでも0か4を設定したAIには割り込まれる事になる。オオカミの場合、EntityAIFollowOwnerも値が3でPriorityがEntityAIAttackMeleeより低いので、プレイヤーに追従時に戦闘に参加した後、プレイヤーから離れても攻撃対象を追いかけ続ける。

    ここで使用されるビット演算はANDなので、整数の2進数表記のリストを見ながら設定すると良い。比較する二つの整数(int値)を2進数に変換したもので、同じ桁同士で両方が1の場合は競合する事になる。例えば(1)は00000001で(3)は00000011なので、双方の1桁目が1なので比較の際に呼び出されるisControlFlagDisabled()ではtrueを返す。

    ビット演算が苦手な人の為に、1~5の競合を記載
     (1):3、5
     (2):3
     (3):1、2、5
     (4):5
     (5):1、3、4

    MineCraft 目次に戻る
  • Minecraft 1.12.2「Golemist」

    こちらはPCゲーム「Minecraft」の自作Mod「Golemist」の解説記事です。

    Minecraft.1.12.2

    Golemist.0.6.61での解説になります。

    Golemist.0.6.61-a現在、マルチプレイで武器を装備したレンガのゴーレムがMobに攻撃をするとクラッシュします。次のアップデートで修正しますのでご了承下さい。








    公開先のサイトはこちら CurseForge Golemist

    Golemistは主にプレイヤーの行動を支援する「ゴーレム」を追加するModです。

    プレイヤー毎に1体だけ入手可能なレンガのゴーレムと、そのペット。

    バイオーム毎にランダムで生成される建物に配置される数種類のゴーレム。

    新規ワールド開始時に各プレイヤーに、そのプレイヤー専用のゴーレムが与えられます。

    ワールド開始時にアイテムとして所持しているので、右クリックで使用する事で、3体のレンガ(人型、犬、馬)のゴーレムを召喚出来ます。

    ここではGolemistの仕様を解説します。

    Modの開発が進むにつれて更新をしていく予定です。

    Modのバージョンによっては仕様が異なるので、ご了承下さい。

    ・ゴーレムが配置される建造物が生成されるバイオームは現在、平地、森、山岳、砂漠、浜辺
    ・各ゴーレムは「ポピー」を右クリックで使用する事で手懐ける事が出来る
    ・手懐けられたゴーレムはオーナーとは当たり判定が発生せず、他のEntityとのみ押し合いが発生する
    ・各ゴーレム(馬のゴーレム以外)はShift+右クリックで「待機」と「追従」を切り替える
    ・「待機」に切り替えた座標が、そのゴーレムのホームポイントに設定され、「待機」状態の時に距離が離れた場合は、そこに戻ろうとする
    ・「待機」状態はバニラのオオカミのとは異なる
    ・手に何も持っていない状態でゴーレムを右クリックすると、プレイヤーのいる座標に引き寄せる事が出来、同時にその座標にホームポイントを再設定する
    ・Iron Golem、Prismarine Golem、Andesite Golem、Stone Golem、Sandstone Golemは戦闘に参加する事が出来る
    ・Wood Golemは攻撃を受けた時またはスライムのみ攻撃する
    ・各ゴーレムはハートが減っている時にスライムを見つけると攻撃してハートを回復する
    ・ハートが0になると、その場に倒れた状態になる
    ・ハートを全回復するか、復活用のアイテムを使用すると起き上がる
    ・ゴーレム毎に装備可能なアイテムが異なる

    Entity

    Unique Golem
    ・レンガのゴーレム(データ上はUnique Golem、Curse Forge内ではFirst Golemと記載)は成長する
    ・新規ワールド開始時にアイテムとして1体だけ入手可能
    ・Pumpkin Rodを持って右クリックする事でGUIを開く事が出来る
    ・他のゴーレムと異なり、数種類の武器と盾を装備できる
    ・装備させられるアイテムを持ってShift+右クリックで装備させることが出来る
    ・GUIからは装備の付け外しが可能
    ・武器の種類はStick、Long Stick、Hoe、Shovel、Pickaxe、Scythe、Axe、Spear、Hammer
    ・各武器は素材と武器種によって能力が異なる
    ・Hoe、Shovel、Pickaxe、Axeは現時点では武器としてしか機能していない
    ・盾は小盾と大盾と、それらにフレームを付けたタイプが存在する
    ・一部のアイテム(投擲可能なアイテム)を拾う
    ・火打石、レンガ、ネザーレンガがインベントリにある場合、状況に応じて投擲する
    ・Catalyst Magic Stick(ゴーレム用スプラッシュポーション)がインベントリにある場合、状況に応じて投擲する
    ・装備の重量により移動速度にペナルティがかかる(現在、調整中)
    ・武器種に依りダメージが増えるMobや追加効果がある
    ・各Mob毎のキル数、全Mobのキル数、武器毎の使用回数で攻撃力が変化する
    ・武器は武器毎に使用する度に、その武器のスキルの熟練度が加算され、攻撃力に反映される
    ・盾は確率で受けるダメージを軽減し、ブロックに成功する度に盾のスキルの熟練度が加算され、ブロック率が上昇していく
    ・武器、盾の熟練度は今後、何かしらのスキルなどの要素のアンロックに使用する(したい)予定

    Wolf Golem
    ・新規ワールド開始時にアイテムとして1体だけ入手可能
    ・同時に出現したUnique Golemと紐付けられ、Unique Golemに追従する
    ・Unique Golemが倒れている時はプレイヤーに追従する
    ・「追従」状態の時は、一定時間ごとにアイテムを拾ってくる事がある
    ・咥えているアイテムは右クリックで回収が可能
    ・Pumpkin Rodを持って右クリックする事でGUIを開く事が出来る
    ・装備させられるアイテムを持ってShift+右クリックで装備させることが出来る
    ・GUIからは装備の付け外しが可能
    ・Unique Golemが使用するCatalyst Magic Stickを持たせる事が出来る
    ・Unique Golemが使用する盾を持たせる事が出来る
    ・アイテムを持たせる為には、専用のアイテムを装備させてアイテムスロットを開放する必要がある

    Horse Golem
    ・新規ワールド開始時にアイテムとして1体だけ入手可能
    ・同時に出現したUnique Golemと紐付けられ、Unique Golemに追従する
    ・Unique Golemが倒れている時はプレイヤーに追従する
    ・Shift+右クリックでUnique Golemが騎乗する
    ・再度、 Shift+右クリックで 降ろす事が出来る
    ・戦闘不能状態のUnique Golemを乗せる事も出来る

    Iron Golem
    ・平地の一軒家に配置されるゴーレム
    ・オーナーが戦闘をしているMobに対して攻撃を仕掛ける
    ・雷に打たれると「帯電」状態になり以後、攻撃力が増加する
    ・「帯電」状態の時にMobを倒すと、そのMobの頭をドロップする(一部のMobのみ)
    ・装備できるアイテムはTwin Shield系
    ・「Guardian Eye」を装備させる事で、対象のターゲットを自身に変更させる能力を得る

    Prismarine Golem
    ・浜辺のライフガードの椅子に配置されるゴーレム
    ・オーナーが戦闘をしているMobに対して攻撃を仕掛ける
    ・倒れた他のゴーレムを運搬する事が出来る
    ・運搬させるには、スニーク状態で倒れているゴーレムにレティクルを合わせ続ける
    ・運搬状態は、運搬されているゴーレムの復活または自身の戦闘不能、右クリックで解除される
    ・炎上中に接触すると炎上が解除される

    Wood Golem
    ・森林のツリーハウスに配置されるゴーレム
    ・植木鉢を装備させる事が出来、Life Essenceを集める事が出来る
    ・「待機」状態の時は、周囲の収穫可能な作物を収穫する(植え直さない)
    ・作物を収穫するか、スライムを倒す毎にLife Essenceが貯まる
    ・貯まったLife Essenceはガラス瓶で汲み出す事が出来る
    ・Life Essenceはゴーレムの復活、ハートの回復に使用する

    Andesite Golem
    ・山岳地帯の砦に配置されるゴーレム
    ・敵対的なMobを見付けると積極的に攻撃を仕掛ける
    ・Stone Golem2体、Stone Supply Cubeと編隊を組んでいる
    ・追従時は部隊の先頭を歩き、他の隊員は後ろに並ぶように追従する
    ・部隊のキル数に応じて「士気」が上昇し攻撃力が上昇する
    ・「士気」は隊員が倒されると減少し、Andesire Golemが倒されると0になる

    Stone Golem
    ・山岳地帯の砦に配置されるゴーレム
    ・敵対的なMobを見付けると積極的に攻撃を仕掛ける
    ・戦闘時以外は隊長(Andesita Golem)に追従する

    Stone Supply Cube
    ・山岳地帯の砦に配置されるゴーレム
    ・戦闘時以外は隊長(Andesita Golem)に追従する
    ・ゴーレムの回復用の液体を貯蔵、運搬する事が出来る
    ・体力が減った他の隊員は非戦闘時に補給の為に接触する
    ・「Guardian Eye」を装備させる事で離れた隊員を回復出来るようになる
    ・運搬出来る液体は「Beetroot」、「Life Essence」
    ・ガラス、板ガラスを装備する事が出来、貯蔵している液体の残量を前面、及び側面から視認できるようになる

    Sandstone Golem
    ・砂漠に潜伏しているゴーレム
    ・オーナーが戦闘をしているMobに対して攻撃を仕掛ける
    ・戦闘時に自身がターゲットされないように攻撃に参加する
    ・洞窟内などでは近くにいるMobを壁越しでも視認できる状態にする

    Clay Golem
    ・村人(Golemist)との取引で入手可能な「Golem Box」を使用すると召喚される
    ・染料を用いて染色する事が出来る
    ・額縁とスライムボールを持ってShift+右クリックで背中に額縁を装着できる
    ・額縁にアイテムをセットする事ができる
    ・素手で左クリックする事で額縁にセットしたアイテムを回収できる
    ・待機状態の時は周囲のアイテムを拾いに行く
    ・手に持っているアイテムは右クリックで回収できる
    ・ホッパーの上を通過すると、額縁にセットされたアイテムと手に持ったアイテムをその場にドロップする

    Hand
    ・枯れ木が植えられた植木鉢に「Bottled Pumpkin Soul」を使用する事でスポーンする
    ・染料を用いて植木鉢を染色する事が出来る
    ・周囲に落ちているアイテムを拾う事が出来る
    ・持っているアイテムを周囲のホッパーに向かって投げ入れようとする
    ・リンゴを右クリックで使用する事で、周囲の畑に種などの作物を投げ植える能力を得る
    ・畑に作物を投げ植える能力を得たHandに金のリンゴを右クリックで使用する事で、周囲の額縁にアイテムを投げるようになる
    ・額縁に投げるアイテムは額縁にセットされたアイテムと同じアイテム
    ・優先順位は、畑、額縁、ホッパーの順になる
    ・周囲を通過したPacPacとClay Golemの持っているアイテムを取り上げる
    ・Clay Golemの場合は手に持ったアイテム、額縁にセットされたアイテムの順に回収
    ・無色のHandはすべての対象からアイテムを回収する
    ・染色されたHandは無色の対象か、自身と同じ色の対象からアイテムを回収する

    PacPac
    ・Handに「Bottled Pumpkin Soul」と「紙」を使用する事でスポーンする
    ・染料を用いて染色する事が出来る
    ・周囲に落ちているアイテムを拾いに行く
    ・周囲にいるHandに拾ったアイテムを届ける
    ・雨に濡れると移動速度が低下する
    ・水没すると即死する

    Freeze
    ・寒冷バイオームにスポーンする
    ・Freeze Rodをドロップする

    Items & Blocks

    ※アイテムのレシピは「Just Enough Items (JEI)」の導入がオススメ
    Bottled Beetroot
    ・ゴーレムの回復に使用する
    ・Brick Cauldronにバケツで水を入れ、ビートルートスープを右クリックで使用すると、Fluid Beetrootに変化する
    ・ビートルートスープをドロップして入れる事も可能だが、ボウルごと消費される
    ・ガラス瓶で汲み出す事が出来て、Stone Supply Cubeに運搬させる事も出来る
    ・ビートルートを10個纏めて投げ入れる事でも作れる
    Bottled Life Essence
    ・ゴーレムの回復に使用する(回復量はBottled Beetrootより多い)
    ・倒されたゴーレムを復活させる効果がある
    ・レンガの大釜に水とガストの涙を入れる事で作る事が出来る
    ・植木鉢を装着したWood Golemが生成する
    Bottled Pumpkin Soul
    ・ゴーレムの回復に使用する(回復量はBottled Life Essenceより多い)
    ・倒されたゴーレムを復活させる効果がある
    ・一部のMobのスポーンの為に使用する
    ・村人(Golemist)との取引での入手か、Wolf Golemが拾ってくる
    Freeze Rod
    ・Freezeがドロップする
    ・Freeze Powderにクラフト出来る
    ・Unique Golemの武器(Stick)としても使用できる
    Freeze Powder
    ・Freeze Rodからクラフトする
    ・Catalyst Magic Powderの材料
    Catalyst Magic Powder
    ・かまどでCatalyst Magic Stickに精錬できる
    ・村人(Golemist)との取引での入手出来る
    ・Armor Ring(ゴーレム用の防具)の素材
    Armor Ring
    ・ゴーレム用のアーマー
    ・アイアンとダイヤモンドのものがクラフト可能
    ・Golemist固有のエンチャントが付与できる
    Leeds
    ・Wolf Golem専用の装備
    ・これを装着する事でWolf Golemに盾を運ばせる事が出来る
    Leather Strap
    ・Leather Wedgeの素材
    Leather Wedge
    ・Wolf Golem専用の装備
    ・これを装着する事でWolf GolemにMagic Stickを運ばせる事が出来る
    Grass Tube
    ・ガラス瓶と同様にGolemistの液体を汲み出せる
    ・16個までスタック可能(ガラス瓶は8個)
    Flint Spike
    ・Andesite Golem、Stone Golem用の武器
    ・Unique Golemが投擲した火打石が砕けてドロップする「Flint Shard」からクラフトする
    Twin Shields
    ・Iron Golem用の武器兼盾
    ・側面からの攻撃のダメージを軽減する
    ・わずかに攻撃力が上昇する
    Unique Golem用の武器
    ・一部の武器はアイテムをShift+右クリックで直接渡す事で専用の武器に変換される
    ・棒、骨、鉄格子、ブレイズロッド、エンドロッド、Freeze Rod、 バニラのクワ類
    ・武器毎に攻撃のモーションが異なる
    ・Unique Golemの攻撃はモーション中に攻撃の当たり判定がある為、空振りが発生する事がある
    ・両手持ちの武器は威力は大きいが振りが遅い為、後退するMobや逃げるMobに空振りする事が多い
    Pumpkin Medal
    ・村人(Golemist)との取引に通貨として使用する
    Small Pumpkin
    ・Pumpkin Lanternの素材
    Flower Pots
    ・植木鉢4個でクラフト
    ・カボチャの種を植える事でSmall Pumpkinを栽培出来る
    Pumpkin Lantern
    ・装飾用アイテム
    ・15レベルの光源
    Brick Cauldron
    ・レンガ7個でクラフト
    ・Golemist専用の液体のクラフトに使用する
    ・回復用の液体が入っている状態で中にゴーレムを入れると、液体を消費してハートを回復する(素手で右クリックでの引き寄せがオススメ)

    Enchantments

    Rune of Thorn(盾)
    ・ブロック成功時に反撃ダメージを与える
    Rune of Ken (武器、盾、アーマー)
    ・炎の能力を付与
    Rune of Is (武器、盾、アーマー)
    ・氷の力を付与
    Rune of Eolh (盾、アーマー)
    ・ダメージ軽減
    Rune of Tir (武器)
    ・ダメージ上昇
    Rune of Beorc (武器、盾)
    ・装備者のハートを回復する
    Rune of Lagu (盾、アーマー)
    ・水の力を付与

    公開先のサイトはこちら CurseForge Golemist

    Minecraft 記事一覧へ


  • Minecraft1.12.2でMod作製 PART9. Golemist-0.6.60

    こちらはPCゲーム「Minecraft」のMod作製日記です。

    Minecraft.1.12.2でのMod作製の作業進捗を書いています。
    Minecraft.1.12.2での完成を目標としていますが、Minecraft.1.13の仕様によってはそちらへ移行してからの完成を目指すかも知れません。









    [要素も充実してきた]

    Mod作製の進捗を、ずっと書かずに進めてて、久しぶりに書こうとしたら、バージョン(0.6.60)まで来てしまってたw

    初めてのアップロードから一年近くも間が開いての日記・・・

    これまでの追加内容や修正内容がかなりの数になるけど、この後リリースする予定の(0.6.60)で出来る事を書いていこう。

    最初のアップロードからJavaの方の扱いも慣れてきて出来る事が多くなってきた。

    例えばif文しか使えなかった頃に書いた無駄に長い記述をfor文やswitch文を使って簡略化したり、アイテムの登録をしやすくするために引数を加えてみたりとか。

    最初に作った処理は解説をしてくれている外国の動画を視ながら作ったものだったから、それと同じ書き方でアイテムやブロック、エンティティを登録していたけど、Javaに慣れてくるにつれて、自分のやりやすい記述に書き換えたり、追記したりできるようになったから後で数値を変更するのも楽になった・・・はずw

    今回のアップデートでユニークゴーレム以外のゴーレムの装備を少し追加して、それに合わせて元々、追加済みだったユニークゴーレム用の装備も記述を書き換えた。

    最近覚えた「列挙型」(Enum)を使って、武器同士の能力の比較や修正をする時に見やすくしたのと、武器に「Material」と「Type」をEnumで記述。

    これによってアイテムを登録する時に、「アイテム名、素材、タイプ」の3つを入力するだけで武器毎の能力を自動で計算して追加してくれるようになった。

    Enumを使うのは元々、アーマーのクラスに書いてあったのを見つけて読み解いて、使い方を覚えたから、Javaが使える人は初めから使ってるんだろうねw

    なんだかんだで、追加出来た要素は・・・

    ・Item(アイテム)

    ・Block(ブロック)

    ・TileEntity(タイルエンティティ)

    ・Entity(エンティティ)

    ・AI

    ・GUI

    ・EntityProjectile(矢、スプラッシュポーションなどがコレ)

    ・Fluid(液体)

    ・Tank(液体タンク)

    ・Enchantment(エンチャント)

    ・Structure(構造物)

    ・Config(コンフィグファイル)

    書いてみると、結構たくさん作ってたw

    少しずつ試行錯誤を繰り返しつつ作ってきた物たちが集まってるから多くても、おかしくはないけど、Javaが読めない状態から考えたら、よく出来たもんだと自分でも関心。

    アイテムやブロックに関してはあまり多くないし、凝ったものも無いから簡単。

    エンティティ関係の追加が本文だから、エンティティやそのAI、今回作ったGUIが大変だったかな。

    以前はユニークゴーレムのモデルのクラスにに武器や盾のモデルも記述してあって、エンティティ側からの情報で、「装備しているか?」を読み取って装備のモデルの描写のon/offを切り替えてたけど、今はちゃんとメインハンドやオフハンドにアイテムを装備させる処理と、装備しているアイテムをゴーレムに描画する処理が出来たから、持たせるだけでok。

    武器に設定した攻撃力も、盾に設定したダメージのカット量も持たせるだけで反映させられる(盾のダメージカットはオリジナルで処理を作った)。

    更にユニークゴーレムしかできてないけど、インベントリとGUIを追加。インベントリは少し前のアップデートからあったけど、GUIは今回から。

    GUIの追加に伴って、ゴーレムのインベントリを作り直して、「インベントリ、武器、盾、アーマー」とスロットを分けてみた。

    これには少してこずったけど、おかげでGUIから装備の受け渡しが出来るようになって、わざわざスニーク状態で右クリックしなくても大丈夫なった。

    ただ、ユニークゴーレムの武器は、バニラのアイテムを渡すと、それに対応した武器に変換されて装備させられるようにしてたから、変換後の武器はGUIから操作できるけど、バニラのアイテムは、手渡しでないといけないw

    GUIに装備変換用のスロットを追加する予定。

    他にも初期の頃は殴るしかできなかった他のゴーレム達も、少しだけど出来る事が多くなってる。

    作物の収穫や種付け、ドロップアイテムの回収やブロックの破壊もできる。ただ一部の作業は、あえて使いにくくしてある。

    ゴーレムは単純な作業しか出来ないっていうイメージを残したいから、作業を分担させたり、他の要素と組み合わせて使う様に遊んでもらいたいかな。

    例えば、追加されているアイテムに「ルーン文字」があるけど、今のバージョンだと「Nied(ニード)」のルーンをゴーレムに張り付けると、ドロップアイテムを拾ってくれるけど、その後は何もしてくれないので、右クリックで受け取る必要がある。

    これだけだと、ドロップアイテムの消滅を防ぐ以外に便利でもなんでもないから、一工夫が必要。

    アイテムを拾ったゴーレムはホッパーの上を通過すると、持ってるアイテム落とす様になってるから、アイテムを拾った後にホッパーの上を通過させるような工夫をすると回収が自動化できる。

    水流で回収するのといい勝負だけど、使い方によっては便利になるかもしれない。

    ブロックの破壊もまだ制約が多い状態。これから修正や追加をしていく予定だけど、まだまだ時間がかかりそう。

    ブロックの破壊は範囲を指定できないようにしてあるから、ゴーレムの周囲の破壊可能なブロックを手当たり次第に破壊していく。

    土ブロックを撤去するのにはいいかなって程度にとどめてある。

    ちなみにブロック破壊は「Hagall(ハガル)」ルーンだけど、用もなく「Rad(ラド)」のルーンと組み合わせてはいけない。

    Radのルーンを付けると、フォローをしなくなって自由行動をしだすから破壊可能なブロックを破壊しながらどこかへ行ってしまうw

    変更予定の部分や仕様の変更もあるから、ある程度出来てくるまで解説などが書けないのが痛いけど、アップデートする時には、変更内容を公開先のサイトに載せてるから大丈夫かな。

    ユーザーからの要望にあった「儀式」も作りたくて考えてるけど、まだ未完成。

    今回のアップデートで儀式や魔法的な要素に関わるエネルギー的な(マナみたいな?)のを運ぶためのエンティティを追加してみた。

    肝心の要素が出来てないから、このエンティティは何もしてくれないけど、とりあえずサッカーボールみたいに転がす事が出来るw

    これを発展させて運べるようにしていく予定(作れたらw)。













    前の記事

    ☆Minecraft1.12.2でMod作製 PRAT8. ModをCurseForgeに公開

    Minecraft 記事一覧へ