実績の追加

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

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

Minecraftに独自の実績ページと、独自の実績を追加します。

目次

[編集] AddAchievementクラスを作成

独自の実績ページと、独自の実績を追加する部分。

注意点として、@Mod.PreInitで実績追加すること。

@Mod.Init前にファイルから実績読み込みが行われるため、その前に追加しておかないと前回起動時に追加したはずの実績が不明な実績として扱われ、実績IDの衝突でクラッシュするため。

package addachievement;
 
import net.minecraft.block.Block;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.Achievement;
import net.minecraftforge.common.AchievementPage;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.registry.LanguageRegistry;
 
@Mod(modid = AddAchievement.modID, name = AddAchievement.modID, version = "1.0")
public class AddAchievement {
	public static final String modID = "AddAchievement";
 
	@SidedProxy(clientSide = "addachievement.ClientProxy", serverSide = "addachievement.CommonProxy")
	public static CommonProxy proxy;
 
	/*
	 * 追加する実績
	 * このサンプルではスカイブロック(http://www.minecraftforum.net/topic/600254-surv-skyblock/)の目標である、
	 * 「黒い羊毛10個を手に入れる」「赤い羊毛10個を手に入れる」を追加するものとする
	 */
	public static Achievement get10BlackWool;
	public static Achievement get10RedWool;
 
	/*
	 * 追加する実績ID
	 * このサンプルでは固定だが、Configで指定できるようにしておくほうがよい
	 */
	public static int get10BlackWoolAchievementID = 21023;
	public static int get10RedWoolAchievementID = 21027;
 
	/*
	 * 実績を追加するページ名
	 * このサンプルではスカイブロックの目標を実績として追加するので「Sky Block」としている
	 */
	public static final String ACHIEVEMENT_PAGE_NAME = "Sky Block";
 
	@Mod.PreInit
	public void preInit(FMLPreInitializationEvent event) {
		/*
		 * 「黒い羊毛10個を手に入れる」の実績を追加
		 * パラメータは、実績ID,実績名(内部名),実績ページの列,実績ページの行,表示するアイコン、の順
		 */
		get10BlackWool = new Achievement(get10BlackWoolAchievementID, "get10BlackWool", 2, 3, new ItemStack(Block.cloth, 1, 15), null).setIndependent().registerAchievement();
 
		/*
		 * 画面に表示する実績名とその説明文を追加する
		 * 日本語の説明文も追加してるが、これはなくてもよい
		 */
		LanguageRegistry.instance().addStringLocalization(get10BlackWool.statName, "en_US", "No.23 Craft 10 Black Wool");
		LanguageRegistry.instance().addStringLocalization(get10BlackWool.statName + ".desc", "en_US", "No.23 Craft 10 Black Wool");
		LanguageRegistry.instance().addStringLocalization(get10BlackWool.statName + ".desc", "ja_JP", "No.23 黒い羊毛を10個手に入れろ!");
 
		/*
		 * 「赤い羊毛10個を手に入れる」の実績を追加
		 * setSpecialメソッドは実績の周りにスパイクを表示するため、隠し実績や達成困難な実績用と思われる
		 */
		get10RedWool = new Achievement(get10RedWoolAchievementID, "get10RedWool", 1, 1, new ItemStack(Block.cloth, 1, 14), null).setIndependent().setSpecial().registerAchievement();
		LanguageRegistry.instance().addStringLocalization(get10RedWool.statName, "en_US", "No.27 Craft 10 Red Wool");
		LanguageRegistry.instance().addStringLocalization(get10RedWool.statName + ".desc", "en_US", "No.27 Craft 10 Red Wool");
 
		/*
		 * 実績ページを追加
		 * AchievementPageのコンストラクタのパラメータは、実績ページ名,実績ページに含まれる実績の配列、の順
		 */
		Achievement[] achievements = new Achievement[] { get10BlackWool, get10RedWool };
		AchievementPage.registerAchievementPage(new AchievementPage(ACHIEVEMENT_PAGE_NAME, achievements));
		proxy.init();
	}
 
}

[編集] CommonProxyクラスを作成

これ以下は実績解除のための処理を実装している

package addachievement;
 
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IGuiHandler;
 
public class CommonProxy implements IGuiHandler {
 
	@Override
	public Object getServerGuiElement(int ID, EntityPlayer player, World world,
			int x, int y, int z) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}
 
	@Override
	public Object getClientGuiElement(int ID, EntityPlayer player, World world,
			int x, int y, int z) {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}
 
	void init() {
		// TODO 自動生成されたメソッド・スタブ
 
	}
 
}

[編集] ClientProxyクラスを作成

package addachievement;
 
import cpw.mods.fml.common.registry.TickRegistry;
import cpw.mods.fml.relauncher.Side;
 
public class ClientProxy extends CommonProxy {
 
	@Override
	void init() {
		TickRegistry.registerTickHandler(new ClientTickHandler(), Side.CLIENT);
	}
}

[編集] ClientTickHandlerクラスを作成

package addachievement;
 
import java.util.EnumSet;
 
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType;
 
public class ClientTickHandler implements ITickHandler {
 
	@Override
	public void tickStart(EnumSet<TickType> type, Object... tickData) {
		// TODO 自動生成されたメソッド・スタブ
 
	}
 
	/*
	 * 実績解除のチェック
	 * このサンプルでは対象のアイテムを手に持った瞬間に実績解除されるようにするために、
	 * Tickごとに手持ちのアイテムが羊毛かつスタック数が10個以上かつ色(=ダメージ値)が実績に対応した値であることをチェックしている
	 */
	@Override
	public void tickEnd(EnumSet<TickType> type, Object... tickData) {
		/*
		 * Tickごとにチェック
		 */
		Minecraft mc = Minecraft.getMinecraft();
		if(mc == null) return;
 
		EntityClientPlayerMP thePlayer = mc.thePlayer;
		if(thePlayer == null) return;
 
		/*
		 * 手に持っているアイテムを参照
		 */
		ItemStack itemStack = thePlayer.getCurrentEquippedItem();
		if(itemStack == null) return;
 
		if(itemStack.itemID == Block.cloth.blockID &&  itemStack.stackSize >= 10) {
			/*
			 * ダメージ値15=黒
			 */
			if(itemStack.getItemDamage() == 15) {
				/*
				 * 「黒い羊毛10個を手に入れる」の実績を解除
				 */
				thePlayer.addStat(AddAchievement.get10BlackWool, 1);
			}
			/*
			 * ダメージ値14=赤
			 */
			if(itemStack.getItemDamage() == 14) {
				/*
				 * 「赤い羊毛10個を手に入れる」の実績を解除
				 */
				thePlayer.addStat(AddAchievement.get10RedWool, 1);
			}
		}
	}
 
	@Override
	public EnumSet<TickType> ticks() {
		return EnumSet.of(TickType.CLIENT);
	}
 
	@Override
	public String getLabel() {
		// TODO 自動生成されたメソッド・スタブ
		return null;
	}
}

[編集] コメント

今回はTick毎に手持ちのアイテムをチェックして実績解除していますが、Eventを使用する等実績解除に利用できるトリガーは色々あります。 実績に合った方法を利用して下さい。

実績ページを追加したとき、場合によっては背景が白くなることがあります。こちらでも紹介されています。
対策の一つとして、親子関係を設定してやると直ることがあります。 このページの例ですと、AddAchievementクラスの
get10RedWool = new Achievement(get10RedWoolAchievementID, "get10RedWool", 1, 1, new ItemStack(Block.cloth, 1, 14), null).setIndependent().setSpecial().registerAchievement();
のnullをget10BlackWoolに変えることでこのバグを直せます。

チュートリアル
個人用ツール