Modding > Peripheral

「Modding/Peripheral」の編集履歴(バックアップ)一覧に戻る
Modding/Peripheral」を以下のとおり復元します。
ComputerCraftに周辺機器を追加するModの製作について解説する。
&color(red){対象:Minecraft Forgeを利用して独自のブロック、アイテムを追加できるModding初級者以上。}

参考資料:
-[[Minecraft Midding Wiki>http://minecraftjp.info/modding/index.php/Minecraft_Modding_Wiki]]
--[[チュートリアル一覧: MinecraftForgeUniversal>http://minecraftjp.info/modding/index.php/%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E4%B8%80%E8%A6%A7#MinecraftForgeUniversal]]
-[[ComputerCraft Forums: Peripherals and Turtle Upgrades>http://www.computercraft.info/forums2/index.php?/forum/17-]]
--[[Creating Peripherals and Turtle Upgrades>http://www.computercraft.info/forums2/index.php?/topic/606-]]
--[[Very Basic Framework (Your First Peripheral)>http://www.computercraft.info/forums2/index.php?/topic/613-]] ※Minecraft 1.2.5時のもの
-[[Minecraft Forge: Tutorials>http://www.minecraftforge.net/wiki/Category:Tutorials]]
執筆時のバージョン:
-ComputerCraft 1.47 for Minecraft 1.4.4

----
#contents
----

*周辺機器追加Modの概要
周辺機器とは、Disk DriveやMonitorのように隣接したComputerやTurtle(以下まとめて「Computer」)から呼び出されて、様々な機能を提供するブロックである。

周辺機器はブロックとして実装し、ブロックのTileEntityに[[IPeripheral>Modding/Peripheral/API]]インターフェイスを実装することで、ComputerCraftから呼び出された時の動作を実装する。そのため、Minecraft Forgeを利用して独自のブロックを追加できる人なら、誰でも簡単に周辺機器追加Modを作ることができる。

*基本的な周辺機器追加Modの例
このサンプルは以下の3クラスからなる。
-TileEntityBasicPeripheral
-BlockBasicPeripheral
-BasicPeripheral
簡略化のため[[Proxyシステム>http://minecraftjp.info/modding/index.php/%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6]]は利用していない。

**TileEntityBasicPeripheral.java
TileEntityのサブクラスにIPeripheralを実装することで、周辺機器としての機能を実装する。IPeripheralの各メソッドについては[[IPeripheral>Modding/Peripheral/API]]を参照。
#highlight(java){{
package sample.peripheral;

import net.minecraft.src.TileEntity;
import dan200.computer.api.IComputerAccess;
import dan200.computer.api.IPeripheral;

public class TileEntityBasicPeripheral extends TileEntity
	implements IPeripheral
{

	@Override
	public String getType()
	{
		return "basicPeripheral";
	}

	@Override
	public String[] getMethodNames()
	{
	    return new String[] { "test" };
	}

	@Override
	public Object[] callMethod( IComputerAccess computer, int method, Object[] arguments )
			throws Exception
	{
		switch( method )
		{
		case 0:
			if( arguments.length < 1 ) {
				throw new Exception("Expected argument");
			}
			return new Object[] { arguments[0] };
		}
		return null;
	}

	@Override
	public boolean canAttachToSide(int side)
	{
		return true;
	}

	@Override
	public void attach( IComputerAccess computer, String computerSide )
	{
		System.out.printf("[BasicPeripheral] %s was attached to Computer #%d (side: %s)\n",
				this.getBlockType().getBlockName(), computer.getID(), computerSide
				);
	}

	@Override
	public void detach( IComputerAccess computer )
	{
		System.out.printf("[BasicPeripheral] %s was detached from Computer #%d\n",
				this.getBlockType().getBlockName(), computer.getID()
				);
	}

} }}

このサンプルでは、周辺機器のタイプ名として&bold(){basicPeripheral}を返し、Computerによってゲーム内で呼び出せる周辺機器のメソッド(以下「周辺機器のメソッド」)として&bold(){test}を実装している。また、周辺機器がComputerと接続(attach)・接続解除(detach)された時に、デバッグ情報として接続・接続解除されたComputerのIDなどを出力している(Minecraftをコマンドラインから実行すると見ることができる)。

Computerから呼び出せる周辺機器の各メソッドの名前は、getMethodNamesの戻り値で指定する。周辺機器の各メソッドの処理は、callMethodで第二引数の値をswitch構文などで分岐させて実装する。周辺機器のメソッドが呼び出された時にComputerから呼び出されるcallMethodの第二引数の値と、呼び出された周辺機器のメソッドの、getMethodNamesの戻り値の配列でのインデックス番号は一致する。

このサンプルの&bold(){test}の場合はgetMethodNamesの戻り値の配列でのインデックス番号が&bold(){0}であるため、ゲーム内で&bold(){test}を呼び出した時にComputerから呼ばれるcallMethodの第二引数の値(int method)は&bold(){0}になる。したがって、methodが&bold(){0}のときに&bold(){test}の処理を実行するように実装すればよい。&bold(){test}の処理の内容は、呼び出し時に引数がなかった場合はComputerにエラーメッセージを表示し、引数があった場合は最初の引数の値を返すというもの。

**BlockBasicPeripheral.java
周辺機器ブロック本体。
BlockContainerのサブクラスとし、createNewTileEntityでIPeripheralを実装したTileEntityのサブクラスのインスタンスを返す。
#highlight(java){{
package sample.peripheral;

import net.minecraft.src.BlockContainer;
import net.minecraft.src.Material;
import net.minecraft.src.TileEntity;
import net.minecraft.src.World;

public class BlockBasicPeripheral extends BlockContainer
{

	protected BlockBasicPeripheral( int blockId, int terrainId, Material material )
	{
		super(blockId, terrainId, material);


	}

	@Override
	public TileEntity createNewTileEntity( World world )
	{
		return new TileEntityBasicPeripheral();
	}
} }}

このサンプルでは、createNewTileEntityで前述のTileEntityBasicPeripheralのインスタンスを返している。

**BasicPeripheral.java
@ModアノテーションによりForge Mod Loaderにロードされるクラス。
#highlight(java){{
package sample.peripheral;

import net.minecraft.src.*;
import net.minecraftforge.common.Configuration;
import net.minecraftforge.common.Property;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkMod;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;

@Mod(modid="BasicPeripheral", name="BasicPeripheral", version="0.0.0", dependencies="after:CCTurtle")
@NetworkMod(clientSideRequired=true, serverSideRequired=false)
public class BasicPeripheral
{
	public int blockIdBasicPeripheral;
	public static Block blockBasicPeripheral;

	@Mod.PreInit
	public void preInit(FMLPreInitializationEvent event)
	{
		Configuration cfg = new Configuration(event.getSuggestedConfigurationFile());
		cfg.load();

		Property Prop = cfg.getBlock("basicPeripheralBlockID", 1211);
		blockIdBasicPeripheral = Prop.getInt();

		cfg.save();
	}

	@Mod.Init
	public void init(FMLInitializationEvent event)
	{
		blockBasicPeripheral = (new BlockBasicPeripheral(blockIdBasicPeripheral, 6, Material.ground))
			.setBlockName("basicPeripheral").setCreativeTab(CreativeTabs.tabBlock);

		GameRegistry.registerBlock(blockBasicPeripheral);

		GameRegistry.registerTileEntity(TileEntityBasicPeripheral.class, "TileEntityBasicPeripheral");

		LanguageRegistry.addName(blockBasicPeripheral, "Basic Peripheral");

		GameRegistry.addRecipe(
			new ItemStack(blockBasicPeripheral, 1),
				new Object[]
				{
					"XXX", "XYX", "XXX",
					Character.valueOf('X'), Block.stone,
					Character.valueOf('Y'), Block.dirt
				});

		CreativeTabs[] tabs = CreativeTabs.creativeTabArray;
		for( int i = 0; i < tabs.length; i++ )
		{
			if( tabs[i].getTabLabel().equals("ComputerCraft")
					|| tabs[i].getTabLabel().equals("BatComputerCraft") )
			{
				blockBasicPeripheral.setCreativeTab(tabs[i]);
			}
		}
		System.out.printf("[BasicPeripheral] Set %s (ID: %d) in Creative Tab: %s\n",
				blockBasicPeripheral.getBlockName(),
				blockBasicPeripheral.blockID,
				blockBasicPeripheral.getCreativeTabToDisplayOn().getTranslatedTabLabel()
				);
	}
} }}

@Modアノテーションを付加したクラスがForge Mod Loaderにロードされる。ここでModの情報も登録している。特筆すべきは&bold(){dependencies="after:CCTurtle"}という値で、これはこのModをComputerCraftよりも後に読み込ませる効果がある。

@Mod.PreInitアノテーションを付加したメソッド(@Mod.Initメソッドの前に呼び出される)preInitでコンフィグファイルを読み込み、サンプル周辺機器のブロックIDを取得している。ブロックIDのデフォルト値は&bold(){1211}。

@Mod.Initアノテーションを付加したメソッド(初期化時に呼び出される)initで周辺機器ブロックやTileEntity、ブロックのレシピを登録している。サンプルの周辺機器ブロックはブロックIDが前述のコンフィグから取得した値で、テクスチャは6面とも石ハーフブロックの上下面と同じ。ゲーム内での表示名は&bold(){Basic Peripheral}。レシピは中央に土ブロックを置き周囲を石ブロックで囲った形。最後に周辺機器ブロックをクリエイティブ・インベントリに登録している。全てのクリエイティブ・タブの中からComputerCraftのタブを検索し、見つかった場合はそこに登録、見つからなかった場合は最初に指定したバニラのBlockタブに登録される。

周辺機器は基本的にComputerから呼び出されて動くため、ここで何かをComputerCraft側に登録するような処理は存在しない。

復元してよろしいですか?