この記事は"Minecraft Forge Universal 10.14.4.x~"及び"ComputerCraft 1.76~"を前提MODとしています。 |
周辺機器の追加
何もしない周辺機器ブロックを追加します。
- IPeripheralの実装
- IPeripheralProviderの実装
- PeripheralProviderの登録
- ブロックの外観の実装
このサンプルでは周辺機器ブロックのレシピを登録していないので、適当なレシピを追加するか、クリエイティブ・インベントリから取り出してください。
ソースコード
Packageは適宜設定してください。
SamplePeripheralCore.java
// package mods.sample.peripheral; import net.minecraft.block.Block; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.registry.GameRegistry; import dan200.computercraft.api.ComputerCraftAPI; @Mod( modid = SamplePeripheralCore.MOD_ID, name = SamplePeripheralCore.MOD_NAME, version = SamplePeripheralCore.MOD_VERSION, dependencies = SamplePeripheralCore.MOD_DEPENDENCIES, acceptedMinecraftVersions = SamplePeripheralCore.MOD_ACCEPTED_MC_VERSIONS) public class SamplePeripheralCore { public static final String MOD_ID = "sampleperipheralmod"; public static final String MOD_NAME = "Sample Peripheral Mod"; public static final String MOD_VERSION = "1.0"; public static final String MOD_DEPENDENCIES = "after:ComputerCraft"; public static final String MOD_ACCEPTED_MC_VERSIONS = "[1.8,1.8.9]"; public static Block blockSamplePeripheral; @EventHandler public void preInit(FMLPreInitializationEvent event) { blockSamplePeripheral = new BlockSamplePeripheral(); GameRegistry.registerBlock(blockSamplePeripheral, "sample_peripheral"); if (event.getSide().isClient()) { ModelLoader.setCustomModelResourceLocation( Item.getItemFromBlock(blockSamplePeripheral), 0, new ModelResourceLocation(MOD_ID + ":" + "sample_peripheral", "inventory")); } } @EventHandler public void init(FMLInitializationEvent event) { GameRegistry.registerTileEntity(TileSamplePeripheral.class, "tile_sample_peripheral"); ComputerCraftAPI.registerPeripheralProvider(new PeripheralProvider()); } }
BlockSamplePeripheral.java
// package mods.sample.peripheral; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; public class BlockSamplePeripheral extends BlockContainer { public BlockSamplePeripheral() { super(Material.ground); setUnlocalizedName("sample_peripheral"); setCreativeTab(CreativeTabs.tabBlock); } @Override public int getRenderType() { return 3; } @Override public TileEntity createNewTileEntity(World world, int a) { return new TileSamplePeripheral(); } }
TileSamplePeripheral.java
// package mods.sample.peripheral; import net.minecraft.tileentity.TileEntity; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; public class TileSamplePeripheral extends TileEntity implements IPeripheral { @Override public String getType() { return "sample"; } @Override public String[] getMethodNames() { return new String[] {}; } @Override public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { switch(method) { } return null; } @Override public void attach(IComputerAccess computer) { } @Override public void detach(IComputerAccess computer) { } @Override public boolean equals(IPeripheral other) { if ((other != null) && (other instanceof TileSamplePeripheral)) { return other == this; } return false; } }
PeripheralProvider.java
// package mods.sample.peripheral; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.World; import dan200.computercraft.api.peripheral.IPeripheral; import dan200.computercraft.api.peripheral.IPeripheralProvider; public class PeripheralProvider implements IPeripheralProvider { @Override public IPeripheral getPeripheral(World world, BlockPos pos, EnumFacing side) { TileEntity tile = world.getTileEntity(pos); if (tile != null && tile instanceof TileSamplePeripheral) { return (TileSamplePeripheral)tile; } return null; } }
sample_peripheral.json (blockstates)
assets\sampleperipheralmod\blockstates ディレクトリに設置します。
{ "variants": { "normal": { "model": "sampleperipheralmod:sample_peripheral" } } }
sample_peripheral.json (models/block)
assets\sampleperipheralmod\models\block ディレクトリに設置します。
{ "parent": "block/cube_all", "textures": { "all": "blocks/stone_slab_top" } }
sample_peripheral.json (models/item)
assets\sampleperipheralmod\models\item ディレクトリに設置します。
{ "parent": "sampleperipheralmod:block/sample_peripheral", "display": { "thirdperson": { "rotation": [ 10, -45, 170 ], "translation": [ 0, 1.5, -2.75 ], "scale": [ 0.375, 0.375, 0.375 ] } } }
解説
SamplePeripheralCore.java
Modのコアとなるクラス
- dependencies
@Mod( dependencies = SamplePeripheralCore.MOD_DEPENDENCIES ) public class SamplePeripheralCore { public static final String MOD_DEPENDENCIES = "after:ComputerCraft";
このmodがComputerCraftの後に読み込まれるように設定しています。
- 周辺機器のブロックとTileEntityの登録
blockSamplePeripheral = new BlockSamplePeripheral(); GameRegistry.registerBlock(blockSamplePeripheral, "sample_peripheral");
GameRegistry.registerTileEntity(TileSamplePeripheral.class, "tile_sample_peripheral");
- モデルとテクスチャを指定しているJSONファイル名の登録
if (event.getSide().isClient()) { ModelLoader.setCustomModelResourceLocation( Item.getItemFromBlock(blockSamplePeripheral), 0, new ModelResourceLocation(MOD_ID + ":" + "sample_peripheral", "inventory")); }
今回は1ブロックIDに対して1モデルだけなので、ファイル名はブロックの登録名と同じにしています。
- PeripheralProviderの登録
ComputerCraftAPI.registerPeripheralProvider(new PeripheralProvider());
接続したComputerへ周辺機器のIPeripheral実装クラスを提供するためのIPeripheralProviderの実装クラス(後述)をComputerCraftに登録します。
これは、自作周辺機器をComputerから使えるようにするために必須です。
BlockSamplePeripheral.java
周辺機器のブロック
- BlockContainerの継承
public class BlockSamplePeripheral extends BlockContainer { @Override public TileEntity createNewTileEntity(World world, int a) { return new TileSamplePeripheral(); } }
周辺機器はTileEntityを持つブロックとして実装するので、BlockContainerを継承し、createNewTileEntity()で周辺機器のTileEntityのインスタンスを生成して返しています。
- RenderTypeの指定
@Override public int getRenderType() { return 3; }
BlockContainerを継承するとRenderTypeが強制的に-1(ブロックが描画されない)になってしまうため、今回は通常のブロックと同じ3を返しています。
TileSamplePeripheral.java
周辺機器のTileEntity兼IPeripheral実装クラス
大体はMC1.7と同じように実装できます。
- IPeripheralの実装
public class TileSamplePeripheral extends TileEntity implements IPeripheral {
今回は周辺機器のTileEntityクラスでIPeripheralも実装しています。
ちなみに、周辺機器は後述のPeripheralProviderでComputerへ提供されるため、IPeripheralはTileEntity以外のクラスで実装することもできます。
- getType()
@Override public String getType() { return "sample"; }
周辺機器の種類を表す文字列を返します。
ゲーム内のLuaプログラムではこの文字列によって周辺機器を検索したり種類を判別したりします。
- getMethodNames()
@Override public String[] getMethodNames() { return new String[] {}; }
Computerから呼び出し可能な周辺機器のメソッド名を表す文字列の配列を返します。
ゲーム内のLuaプログラムではperipheral.getMethods()の戻り値になります。
今回は周辺機器のメソッドを実装しないので空の配列を返しています。
- callMethod()
@Override public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException { switch(method) { } return null; }
Computerからperipheral.call()で周辺機器のメソッドを呼び出したときの処理を実装します。
仮引数methodに渡される値は、getMethodNames()の戻り値で添字[method]に相当するメソッドが呼び出されたことを示します。
今回はメソッドを実装しないので何もしません。
- attach()とdetach()
@Override public void attach(IComputerAccess computer) { } @Override public void detach(IComputerAccess computer) { }
周辺機器ブロックがComputerに接続されたとき(attach)と、取り外されたとき(detach)に呼び出されます。
今回は何もしません。
- equals()
@Override public boolean equals(IPeripheral other) { if ((other != null) && (other instanceof TileSamplePeripheral)) { return other == this; } return false; }
Computerに周辺機器が着脱されたときに現在取り付けられている周辺機器(this)が、それまで取り付けられていた周辺機器(other)と同一かどうかを調べるために呼び出されます。
周辺機器のTileEntityインスタンスが同一かどうかを比較して返しています。
PeripheralProvider.java
Computerへ周辺機器(IPeripheralの実装クラス)を提供するためのクラス
- IPeripheralProviderの実装
public class PeripheralProvider implements IPeripheralProvider {
IPeripheralProviderを実装します。
前述の通り、このクラスのインスタンスをComputerCraftAPI.registerPeripheralProvider()でComputerCraftへ登録します。
- getPeripheral()
@Override public IPeripheral getPeripheral(World world, BlockPos pos, EnumFacing side) { TileEntity tile = world.getTileEntity(pos); if (tile != null && tile instanceof TileSamplePeripheral) { return (TileSamplePeripheral)tile; } return null; }
周辺機器がComputerへ接続されたときに呼び出されます。posは周辺機器のブロック座標、sideは周辺機器側から見た接続方向です。
今回は周辺機器のTileEntityでIPeripheralを実装したため、座標から周辺機器のTileEntityを取得し、IPeripheralのインスタンスとして返しています。
sample_peripheral.json (blockstates)
BlockState別のモデルJSONファイルの指定を行います。
assets\<MOD_ID>\blockstates ディレクトリに配置します。
今回の周辺機器ブロックはBlockStateが無いので、"noemal"で単一のモデルJSONファイルを指定しています。
sample_peripheral.json (models/block)
ブロックのモデルを指定するJSONファイルです。
assets\<MOD_ID>\models\block ディレクトリに設置します。
今回は6面とも同じテクスチャで構成するため"parent"には"block/cube_all"を指定しています。
また、テクスチャにはバニラの石半ブロックの上面の画像を指定しています。
sample_peripheral.json (models/item)
ブロックのアイテムモデルを指定するJSONファイルです。
assets\<MOD_ID>\models\item ディレクトリに設置します。
今回は"parent"で親としてブロックのモデルを指定しています。
また、"display"以下で座標変換パラメータを指定しています。
詳しくはチュートリアル「1.8のブロック追加」を参照してください。