提供: Minecraft Modding Wiki
移動先: 案内検索
(「AchievementPage」のローカライズ機能のあたりが中途半端だったので修正)
(実績の依存関係について、実績ツリー上のアイコンの配置について、実績ページについて加筆)
 
(同じ利用者による、間の5版が非表示)
7行目: 7行目:
 
「net.minecraft.stats.Achievement」は、「net.minecraft.stats.StatBase」のサブクラスで、実績の名称(例えば、「所持品の確認」)や実績ツリー([http://minecraft-ja.gamepedia.com/%E5%AE%9F%E7%B8%BE#.E3.82.A4.E3.83.B3.E3.82.BF.E3.83.BC.E3.83.95.E3.82.A7.E3.83.BC.E3.82.B9 Minecraft Wiki/実績#インターフェース])内の位置などを格納するクラスです。
 
「net.minecraft.stats.Achievement」は、「net.minecraft.stats.StatBase」のサブクラスで、実績の名称(例えば、「所持品の確認」)や実績ツリー([http://minecraft-ja.gamepedia.com/%E5%AE%9F%E7%B8%BE#.E3.82.A4.E3.83.B3.E3.82.BF.E3.83.BC.E3.83.95.E3.82.A7.E3.83.BC.E3.82.B9 Minecraft Wiki/実績#インターフェース])内の位置などを格納するクラスです。
  
Forgeは、ある実績のまとまりを「ページ」として、SwingのCardLayoutのように切り替える機能を追加しています。この機能によって、例えばModごとに(あるいはModの主要な目標ごとに)新しいページを追加することで、一つのページのまとまりが失われるのを防ぐことができるでしょう。この「ページ」は、「net.minecraftforge.common.AchievementPage」を使って表現します。「AchievementPage」のコンストラクタの第一引数は、「AchievementPage」の名前です。バニラの「ページ」の名前は、「Minecraft」となっています。[[ローカライズについて|ローカライズ機能]]は用意されていないので、欲しい方は継承等で対応しましょう。
+
Achievementのコンストラクタは3種類あり、それぞれ実績ツリー上で表示されるアイコンに使う要素として第五引数にBlockを渡すか、Itemを渡すか、ItemStackを渡すかでどれを使うか選びます。
  
プレイヤーに実績を獲得させるときは、「net.minecraft.entity.player.EntityPlayer#addStat」を呼び出します。この第一引数はStatBase型を取り、「Achievement」を渡します。「EntityPlayer#addStat」には、第二引数としてint型の「amount」を取るものもありますが、これは「統計」の操作に関与します。「統計」は「Achievement」と同じく「StatBase」のサブクラスである「net.minecrfat.stats.StatBasic」で表現します。こちらも扱ってみたい方は、[[1.11の統計追加]]を参照するとよいでしょう。
+
Achievementのコンストラクタの第一引数には、実績を特定する固有のIDをString型で渡します。第二引数には、[[ローカライズについて|ローカライズ]]前の実績の名称の「一部」を渡します(「一部」については後で述べる)。int型の第三引数には実績ツリー上の列座標(横方向、右が正)、同じくint型の第四引数には実績ツリー上の行座標(縦方向、下が正)を渡します(列座標、行座標については後で述べる)。第五引数には、先に述べたように実績アイコンとして表示するBlock、Item、またはItemStackのインスタンスを渡します。Achievement型の第六引数には、「親」となるAchievementのインスタンスを渡します。ここで「親」というのは、実績ツリー上で矢印の根本になる実績を指します。「親」にはnullを指定することができます。「親」がnullの場合、実績ツリー上で矢印は描画されません。また、「親」がnullでない実績は、「親」の実績が獲得された後でしか獲得することができません。
 +
 
 +
 第二引数について「一部」と述べたのは、実際に言語ファイルに記述するローカライズキーは、「achievement.<第二引数>」になるからです。また、この第二引数は実績の「説明」のローカライズキーにも使用されます。実績の「説明」は、実績ツリー上で実績の名称の下に表示される文字列(例えば、【「E」を押してインベントリを開く】)です。実績の「説明」のローカライズキーは、「achievement.<第二引数>.desc」になります。
 +
 
 +
 第三、第四引数は、実績ツリー上におけるアイコンの描画位置に関与しますが、整数で「1」離れた値を指定したとしてもアイコンが重なることはありません。アイコンは24ピクセル単位で、グリッド状に配置されます。また、0を指定すると実績ツリーの中心付近に表示され(「所持品の確認」は0列、0行)、負の値を指定することもできます(バニラでも負の値が使われています。例えば「土台作り」は4列、-1行)。
 +
 
 +
Forgeはゲーム中のメインメニューから開ける実績GUIにおいて、ある実績のまとまりを「ページ」として、SwingのCardLayoutのように表示する実績を切り替える機能を追加しています。この機能によって、例えばModごとに(あるいはModの主要な目標ごとに)新しいページを追加することで、一つのページのまとまりが失われるのを防ぐことができるでしょう。
 +
 
 +
この「ページ」は、「net.minecraftforge.common.AchievementPage」を使って表現します。「AchievementPage」のコンストラクタの第一引数には、「AchievementPage」の名前を渡します。[[ローカライズについて|ローカライズ機能]]は用意されていないので、欲しい方は継承等で対応しましょう。可変長引数である第二引数には、この「AchievementPage」に含む「Achievement」のインスタンスを渡します。
 +
 
 +
なお、バニラの「ページ」の名前は、「Minecraft」となっています。ただし、バニラの「AchievementPage」インスタンスは存在せず、ForgeがGUI側(net.minecraft.client.gui.achievement.GuiAchievements)に追加したフックで、ある「Achievement」がModの「AchievementPage」に含まれていないと判定されれば、バニラの「ページ」に表示されるようになっています。
 +
 
 +
「Achievement」のインスタンスは、「Achievement#registerStat」を呼び出すことでゲーム内に実績として追加することができます。バニラの実績を扱うときは、「net.minecraft.stats.AchievementList」にあるAchievementのstaticなインスタンスを使用します。
 +
 
 +
また、「AchievementPage」のインスタンスは、staticメソッド「AchievementPage#registerAchievementPage」を呼び出して登録する必要があります。
 +
 
 +
プレイヤーに実績を獲得させるときは、「net.minecraft.entity.player.EntityPlayer#addStat」を呼び出します。この関数の第一引数はStatBase型を取り、「Achievement」を渡します。先に述べたように、引数に渡す実績の「親」の実績を獲得していない場合は「EntityPlayer#addStat」を呼んでも無視されます。
 +
 
 +
 +
<source lang="java">
 +
player.addStat(ACHIEVEMENT_SAMPLE);
 +
</source>
 +
 
 +
「EntityPlayer#addStat」には、第二引数としてint型の「amount」を取るものもありますが、これは「統計」の操作に関与します。「統計」は「Achievement」と同じく「StatBase」のサブクラスである「net.minecrfat.stats.StatBasic」で表現します。こちらも扱ってみたい方は、[[1.11の統計追加]]を参照するとよいでしょう。
  
前提条件などでバニラの実績を扱いたいときは、「net.minecraft.stats.AchievementList」にバニラのAchievementのstaticなインスタンスがあります。
 
  
 
=== 落下実績の追加 ===
 
=== 落下実績の追加 ===
17行目: 39行目:
  
 
15mの落下でHard Landing(難着陸)、30mの落下でHigh Flyer(高く飛ぶ者、野心家)を獲得します。
 
15mの落下でHard Landing(難着陸)、30mの落下でHigh Flyer(高く飛ぶ者、野心家)を獲得します。
 +
 +
elseを使わずif文を並べているので、一度30m落下すれば15mの実績と30mの実績が同時に獲得できます。
  
 
==== ソースコード ====
 
==== ソースコード ====
23行目: 47行目:
 
package samplemod;
 
package samplemod;
  
import net.minecraft.block.Block;
 
 
import net.minecraft.entity.player.EntityPlayer;
 
import net.minecraft.entity.player.EntityPlayer;
 
import net.minecraft.init.Items;
 
import net.minecraft.init.Items;

2017年3月28日 (火) 22:47時点における最新版

この記事は"Minecraft Forge Universal 13.19.0.xxx~"を前提MODとしています。

Wood pickaxe.png
初心者向けのチュートリアルです。
C player.png
Playerに関係のあるチュートリアルです。


実績の追加[編集]

Achievement[編集]

「net.minecraft.stats.Achievement」は、「net.minecraft.stats.StatBase」のサブクラスで、実績の名称(例えば、「所持品の確認」)や実績ツリー(Minecraft Wiki/実績#インターフェース)内の位置などを格納するクラスです。

Achievementのコンストラクタは3種類あり、それぞれ実績ツリー上で表示されるアイコンに使う要素として第五引数にBlockを渡すか、Itemを渡すか、ItemStackを渡すかでどれを使うか選びます。

Achievementのコンストラクタの第一引数には、実績を特定する固有のIDをString型で渡します。第二引数には、ローカライズ前の実績の名称の「一部」を渡します(「一部」については後で述べる)。int型の第三引数には実績ツリー上の列座標(横方向、右が正)、同じくint型の第四引数には実績ツリー上の行座標(縦方向、下が正)を渡します(列座標、行座標については後で述べる)。第五引数には、先に述べたように実績アイコンとして表示するBlock、Item、またはItemStackのインスタンスを渡します。Achievement型の第六引数には、「親」となるAchievementのインスタンスを渡します。ここで「親」というのは、実績ツリー上で矢印の根本になる実績を指します。「親」にはnullを指定することができます。「親」がnullの場合、実績ツリー上で矢印は描画されません。また、「親」がnullでない実績は、「親」の実績が獲得された後でしか獲得することができません。

 第二引数について「一部」と述べたのは、実際に言語ファイルに記述するローカライズキーは、「achievement.<第二引数>」になるからです。また、この第二引数は実績の「説明」のローカライズキーにも使用されます。実績の「説明」は、実績ツリー上で実績の名称の下に表示される文字列(例えば、【「E」を押してインベントリを開く】)です。実績の「説明」のローカライズキーは、「achievement.<第二引数>.desc」になります。

 第三、第四引数は、実績ツリー上におけるアイコンの描画位置に関与しますが、整数で「1」離れた値を指定したとしてもアイコンが重なることはありません。アイコンは24ピクセル単位で、グリッド状に配置されます。また、0を指定すると実績ツリーの中心付近に表示され(「所持品の確認」は0列、0行)、負の値を指定することもできます(バニラでも負の値が使われています。例えば「土台作り」は4列、-1行)。

Forgeはゲーム中のメインメニューから開ける実績GUIにおいて、ある実績のまとまりを「ページ」として、SwingのCardLayoutのように表示する実績を切り替える機能を追加しています。この機能によって、例えばModごとに(あるいはModの主要な目標ごとに)新しいページを追加することで、一つのページのまとまりが失われるのを防ぐことができるでしょう。

この「ページ」は、「net.minecraftforge.common.AchievementPage」を使って表現します。「AchievementPage」のコンストラクタの第一引数には、「AchievementPage」の名前を渡します。ローカライズ機能は用意されていないので、欲しい方は継承等で対応しましょう。可変長引数である第二引数には、この「AchievementPage」に含む「Achievement」のインスタンスを渡します。

なお、バニラの「ページ」の名前は、「Minecraft」となっています。ただし、バニラの「AchievementPage」インスタンスは存在せず、ForgeがGUI側(net.minecraft.client.gui.achievement.GuiAchievements)に追加したフックで、ある「Achievement」がModの「AchievementPage」に含まれていないと判定されれば、バニラの「ページ」に表示されるようになっています。

「Achievement」のインスタンスは、「Achievement#registerStat」を呼び出すことでゲーム内に実績として追加することができます。バニラの実績を扱うときは、「net.minecraft.stats.AchievementList」にあるAchievementのstaticなインスタンスを使用します。

また、「AchievementPage」のインスタンスは、staticメソッド「AchievementPage#registerAchievementPage」を呼び出して登録する必要があります。

プレイヤーに実績を獲得させるときは、「net.minecraft.entity.player.EntityPlayer#addStat」を呼び出します。この関数の第一引数はStatBase型を取り、「Achievement」を渡します。先に述べたように、引数に渡す実績の「親」の実績を獲得していない場合は「EntityPlayer#addStat」を呼んでも無視されます。

player.addStat(ACHIEVEMENT_SAMPLE);

「EntityPlayer#addStat」には、第二引数としてint型の「amount」を取るものもありますが、これは「統計」の操作に関与します。「統計」は「Achievement」と同じく「StatBase」のサブクラスである「net.minecrfat.stats.StatBasic」で表現します。こちらも扱ってみたい方は、1.11の統計追加を参照するとよいでしょう。


落下実績の追加[編集]

プレイヤーが一定距離を落下した際に追加実績を得るようにするサンプルです。

15mの落下でHard Landing(難着陸)、30mの落下でHigh Flyer(高く飛ぶ者、野心家)を獲得します。

elseを使わずif文を並べているので、一度30m落下すれば15mの実績と30mの実績が同時に獲得できます。

ソースコード[編集]

SampleMod.java

package samplemod;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.stats.Achievement;
import net.minecraftforge.common.AchievementPage;
import net.minecraftforge.event.entity.living.LivingFallEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;

@Mod(modid = SampleMod.MOD_ID, name = SampleMod.MOD_NAME, version = SampleMod.VERSION)
public class SampleMod {
    public static final String MOD_ID = "samplemod";
    public static final String MOD_NAME = "Sample Mod";
    public static final String VERSION = "0.1.0";


    public static final Achievement achievement_fall_15m =
            new Achievement("achievement." + MOD_ID + ":fall_15m", MOD_ID + ".fall_15m",
                    0, 0, Items.FEATHER, null).registerStat();

    public static final Achievement achievement_fall_30m =
            new Achievement("achievement." + MOD_ID + ":fall_30m", MOD_ID + ".fall_30m",
                    2, 0, Items.ELYTRA, achievement_fall_15m).registerStat();

    public static final AchievementPage achievement_page_fall = new AchievementPage("Sample Mod",
            achievement_fall_15m,
            achievement_fall_30m
    );

    @Mod.EventHandler
    public void preInit(FMLPreInitializationEvent event) {
        AchievementPage.registerAchievementPage(achievement_page_fall);
    }

    @Mod.EventBusSubscriber
    public static class Handler {
        @SubscribeEvent
        public static void onFall(LivingFallEvent event) {
            if (event.getEntity() instanceof EntityPlayer) {
                EntityPlayer player = (EntityPlayer) event.getEntity();

                float d = event.getDistance();

                if (15f <= d) {
                    player.addStat(achievement_fall_15m);
                }

                if (30f <= d) {
                    player.addStat(achievement_fall_30m);
                }
            }
        }
    }

}

assets/samplemod/lang/en_US.lang

# Sample Mod Translation File [en_US]

achievement.samplemod.fall_15m=Hard Landing
achievement.samplemod.fall_15m.desc=Experience 15m Fall
achievement.samplemod.fall_30m=High Flyer
achievement.samplemod.fall_30m.desc=Experience 30m Fall