Modding > TurtleUpgrade

「Modding/TurtleUpgrade」の編集履歴(バックアップ)一覧はこちら

Modding/TurtleUpgrade」(2013/05/30 (木) 00:47:27) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

ComputerCraftにTurtleアップグレードを追加する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-]] -[[ComputerCraft Wiki: Turtle Upgrade IDs>http://www.computercraft.info/wiki/index.php?title=Turtle_Upgrade_IDs]] -[[Minecraft Forge: Tutorials>http://www.minecraftforge.net/wiki/Category:Tutorials]] 執筆時のバージョン: -ComputerCraft 1.52 for Minecraft 1.5.1 ---- #contents ---- *Turtleアップグレード追加Modの概要 Turtleアップグレードとは、Digging TurtleやCrafty Turtleのように、Turtleにアイテムやブロックを装着(クラフト)することによって機能を追加することができるシステムである。 **アップグレードの実装 TurtleアップグレードはITurtleUpgradeインターフェイスの実装クラスとして機能を実装し、その実装クラスをComputerCraftに登録することによってTurtleに装着できるようになる。機能追加に関するAPIも用意されているため、簡単に作ることができる。 **アップグレードのタイプ Turtleアップグレードには以下の2タイプがある。 -[[turtle.digやturtle.attack>API/Turtle]]で作動する&bold(){Tool}タイプ(例:ダイヤシャベルでDigging Turtle) -[[Peripheral API>API/Peripheral]]で作動する&bold(){Peripheral}タイプ(例:作業台でCrafty Turtle) Turtleアップグレードを製作するときは、どちらか一方のタイプを選択する必要がある。今のところ1つのTurtleには、1つのToolタイプと1つのPeripheralタイプ、または2つのPeripheralタイプを装着することができる(例:ダイヤクワ(Tool)とWireless Modem(Peripheral)でWireless Farming Turtle)。 **アップグレードID Turtleアップグレードには他のTurtleアップグレードと重複しないID番号を割り当てる必要がある。Mod製作者が割り当て可能なIDの範囲は【-1.52】では64~255、【1.53-】では64~32767である。既に配布されているModが使用しているTurtleアップグレードIDは[[ComputerCraft Wiki>http://www.computercraft.info/wiki/index.php?title=Turtle_Upgrade_IDs]]で確認することができる。 *基本的なTurtleアップグレード追加Modの例 ToolタイプとPeripheralタイプのTurtleアップグレードを追加する。 このサンプルは以下の4クラスからなる。 -BasicUpgrades -TurtleBasicTool -TurtleBasicPeripheral -PeripheralTurtleBasicPeripheral 簡略化のため[[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]]は利用していない。 なお、このサンプルmodの前提modは【MinecraftForge】と【ComputerCraft】である。 **BasicUpgrades.java Modのメインクラス。@ModアノテーションによりForgeModLoaderにロードされる。 #highlight(java){{ package sample.upgrade; import net.minecraftforge.common.Configuration; import net.minecraftforge.common.Property; import cpw.mods.fml.common.Loader; 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 dan200.turtle.api.TurtleAPI; @Mod(modid="BasicUpgrades", name="BasicUpgrades", version="0.0.0", dependencies="after:CCTurtle") @NetworkMod(clientSideRequired=true, serverSideRequired=false) public class BasicUpgrades { public static int basicToolUpgradeID; public static int basicPeripheralUpgradeID; @Mod.PreInit public void preInit(FMLPreInitializationEvent event) { Property Prop; Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); cfg.load(); Prop = cfg.get("upgrade", "basicToolUpgradeID", 110); basicToolUpgradeID = Prop.getInt(); Prop = cfg.get("upgrade", "basicPeripheralUpgradeID", 111); basicPeripheralUpgradeID = Prop.getInt(); cfg.save(); } @Mod.Init public void init(FMLInitializationEvent event) { TurtleAPI.registerUpgrade(new TurtleBasicTool()); TurtleAPI.registerUpgrade(new TurtleBasicPeripheral()); } } }} @Modアノテーションを付加したクラスがForge Mod Loaderにロードされる。ここでModの情報も登録している。特筆すべきは&bold(){dependencies="after:CCTurtle"}という値で、これはこのModをComputerCraftよりも後に読み込ませる効果がある。 @Mod.PreInitアノテーションを付加したメソッド&bold(){preInit}(@Mod.Initメソッドの前に呼び出される)でコンフィグファイルを読み込み、TurtleアップグレードIDのブロックIDを取得している。ToolアップグレードIDのデフォルト値は&bold(){110}、PeripheralアップグレードIDのデフォルト値は&bold(){111}。 @Mod.Initアノテーションを付加したメソッド&bold(){init}(初期化時に呼び出される)でComputerCraftにTurtleアップグレードを登録している。TurtleアップブレードのクラスをTurtleAPI.registerUpgrade()で登録することにより、そのTurtleアップグレードがゲーム中で使用可能になる。 **TurtleBasicTool.java ITurtleUpgradeの実装クラスでToolタイプのTurtleアップグレードを実装している。このクラスで、アップグレードをTurtleに装着するためのアイテム(装着レシピはComputerCraftによる自動追加)や、装着後の外観、採掘・攻撃時の動作などを指定することができる。 このサンプルでは、簡単な採掘と攻撃ができるようになっている。 #highlight(java){{ package sample.upgrade; import java.util.ArrayList; import java.util.Iterator; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.Facing; import net.minecraft.util.Icon; import net.minecraft.util.Vec3; import net.minecraft.world.World; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.ITurtleUpgrade; import dan200.turtle.api.TurtleSide; import dan200.turtle.api.TurtleUpgradeType; import dan200.turtle.api.TurtleVerb; public class TurtleBasicTool implements ITurtleUpgrade { public ItemStack upgradeItem = new ItemStack(Item.pickaxeGold); @Override public int getUpgradeID() { return BasicUpgrades.basicToolUpgradeID; } @Override public String getAdjective() { return "Tool"; } @Override public TurtleUpgradeType getType() { return TurtleUpgradeType.Tool; } @Override public ItemStack getCraftingItem() { return upgradeItem; } @Override public boolean isSecret() { return false; } @Override public IHostedPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) { return null; } @Override public boolean useTool(ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, int direction) { switch( verb ) { case Dig: return dig(turtle, direction); case Attack: return attack(turtle, direction); } return false; } private boolean dig(ITurtleAccess turtle, int dir) { World world = turtle.getWorld(); Vec3 position = turtle.getPosition(); if (position == null) { return false; } int newX = (int)position.xCoord + Facing.offsetsXForSide[dir]; int newY = (int)position.yCoord + Facing.offsetsYForSide[dir]; int newZ = (int)position.zCoord + Facing.offsetsZForSide[dir]; if ( (newY < 0) || (newY >= world.getHeight()) ) { return false; } int blockID = world.getBlockId(newX, newY, newZ); Block block = Block.blocksList[blockID]; if ( (blockID == 0) || (blockID == Block.bedrock.blockID) || (block.getBlockHardness(world, newX, newY, newZ) <= -1.0F) ) { return false; } int matadata = world.getBlockMetadata(newX, newY, newZ); ArrayList items = block.getBlockDropped(world, newX, newY, newZ, matadata, 0); Iterator it = items.iterator(); while (it.hasNext()) { ItemStack item = (ItemStack)it.next(); if ( !turtle.storeItemStack(item) ) { int[] oppositeSide = { 1, 0, 3, 2, 5, 4 }; if ( !turtle.dropItemStack(item, oppositeSide[turtle.getFacingDir()]) ) { turtle.dropItemStack(item, turtle.getFacingDir()); } } } world.playAuxSFX(2001, newX, newY, newZ, blockID + matadata * 4096); world.setBlock(newX, newY, newZ, 0, 0, 3); return true; } private boolean attack(ITurtleAccess turtle, int dir) { return turtle.attackWithItemStack(new ItemStack(Item.swordDiamond), dir, 2.0F); } @Override public Icon getIcon(ITurtleAccess turtle, TurtleSide side) { return upgradeItem.getIconIndex(); } } }} TurtleアップグレードIDはgetUpgradeIDの戻り値で指定する。このサンプルでは前述の@MODクラスBasicUpgradesのメンバー変数から取得して指定している。アップグレードのタイプはenum TurtleUpgradeTypeの列挙子でToolを指定。装着したTurtleに付く形容詞は"Tool"を指定(つまり"Tool Turtle"になる)。クラフトに必要なアイテムと装着したアップグレードの外観は金のツルハシ。Toolタイプなので無用なcreatePeripheralではnullを返す。 Toolタイプの本領はuseToolによって発揮される。このサンプルではverbの種類(DigかAttackか)で分岐させた後、それぞれ別のメンバー関数(digとattack)に処理させている。 -dig Turtleに採掘させる場合、採掘に必要な処理そのものを書く必要がある。 まず、useToolから得たITurtleAccess turtleによりTurtleの座標を得て、その座標と採掘する方向dirから採掘すべきブロックの座標と種類、メタデータを取得する。次に、採掘すべきブロックが採掘できるか(高度、種類)を調べる。採掘可能だった場合は採掘して得られるアイテムを取得し、スロットに入りきらなかった場合はドロップする。最後に採掘の効果音を鳴らし、採掘したブロックを消す(空気ブロックにする)。 -attack 採掘処理が難しい一方で、攻撃は専用メソッドが用意されているため簡単である。このサンプルではダイヤソードの2倍の攻撃力14(ハート7個分)でdir方向を攻撃する。 ちなみに、それぞれのverdは単にTurtle側のturtle.dig()とturtle.attack()で呼び出されるというだけで、必ずしもTurtleが採掘や攻撃を行わなければならないという訳ではない。 **TurtleBasicPeripheral.java ITurtleUpgradeの実装クラスでPeripheralタイプのTurtleアップグレードを実装している。 #highlight(java){{ package sample.upgrade; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.util.Icon; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.ITurtleUpgrade; import dan200.turtle.api.TurtleSide; import dan200.turtle.api.TurtleUpgradeType; import dan200.turtle.api.TurtleVerb; public class TurtleBasicPeripheral implements ITurtleUpgrade { public ItemStack upgradeItem = new ItemStack(Block.stone, 1, 0); @Override public int getUpgradeID() { return BasicUpgrades.basicPeripheralUpgradeID; } @Override public String getAdjective() { return "Peripheral"; } @Override public TurtleUpgradeType getType() { return TurtleUpgradeType.Peripheral; } @Override public ItemStack getCraftingItem() { return upgradeItem; } @Override public boolean isSecret() { return false; } @Override public IHostedPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) { return new PeripheralTurtleBasicPeripheral(turtle, side); } @Override public boolean useTool(ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, int direction) { return false; } @Override public Icon getIcon(ITurtleAccess turtle, TurtleSide side) { return Block.stoneSingleSlab.getBlockTextureFromSide(0); } } }} TurtleアップグレードIDはgetUpgradeIDの戻り値で指定する。このサンプルでは前述の@MODクラスBasicUpgradesのメンバー変数から取得して指定している。アップグレードのタイプはenum TurtleUpgradeTypeの列挙子でPeripheralを指定。装着したTurtleに付く形容詞は"Peripheral"を指定(つまり"Peripheral Turtle"になる)。クラフトに必要なアイテムは石ブロック。装着したアップグレードの外観は石ハーフブロックの下面。 Peripheralタイプなので、createPeripheralでは周辺機器の機能を実装したIHostedPeripheralの実装クラスのインスタンスを返す。このサンプルでは、後述のPeripheralTurtleBasicPeripheralのインスタンスを返している。ToolタイプではないのでuseToolは呼び出されない。 **PeripheralTurtleBasicPeripheral.java IHostedPeripheralの実装クラスでPeripheralタイプのアップグレードの周辺機器としての動作を実装している。IHostedPeripheralはIPeripheralのサブインターフェイスである。[[周辺機器ブロック追加Mod>Modding/Peripheral]]も参照のこと。 #highlight(java){{ package sample.upgrade; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import dan200.computer.api.IComputerAccess; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.TurtleSide; public class PeripheralTurtleBasicPeripheral implements IHostedPeripheral { private ITurtleAccess m_turtle; private IComputerAccess m_computer; private TurtleSide m_side; PeripheralTurtleBasicPeripheral(ITurtleAccess turtle, TurtleSide side) { m_turtle = turtle; m_side = side; } @Override public String getType() { return "turtlebasic"; } @Override public String[] getMethodNames() { return new String[] { "test", "getPosition" }; } @Override public Object[] callMethod( IComputerAccess computer, int method, Object[] arguments ) throws Exception { switch( method ) { case 0: // test if( arguments.length < 1 ) { throw new Exception("Expected argument"); } return new Object[] { arguments[0] }; case 1: //getPosition Vec3 pos = m_turtle.getPosition(); if( arguments.length > 0 && arguments[0] instanceof Boolean && true == (Boolean)arguments[0]) { return new Object[] { "Position: " + (int)pos.xCoord + ", " + (int)pos.yCoord + ", " + (int)pos.zCoord }; } return new Object[] { Integer.valueOf((int)pos.xCoord), Integer.valueOf((int)pos.yCoord), Integer.valueOf((int)pos.zCoord) }; } return null; } @Override public boolean canAttachToSide(int side) { return true; } @Override public void attach( IComputerAccess computer) { m_computer = computer; System.out.printf("[TurtleBasicPeripheral] Attached to Computer #%d (side: %s)\n", m_computer.getID(), m_computer.getAttachmentName() ); } @Override public void detach( IComputerAccess computer ) { System.out.printf("[TurtleBasicPeripheral] Detached from Computer #%d\n", computer.getID() ); } @Override public void update() { } @Override public void readFromNBT(NBTTagCompound nbttagcompound) { } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { } } }} [[周辺機器ブロック追加Mod>Modding/Peripheral]]と似たような構成になっているが、以下のような点が違う。 -attachはTurtle起動時、detachはattach後のTurtle破壊時に呼び出される(Turtleアップグレードの特徴) -attach後に毎Tick呼び出されるupdateが追加されている(IHostedPeripheralの特徴) -NBTへデータを読み書きするメソッドが追加されている(IHostedPeripheralの特徴) このサンプルではタートルへのアクセスインターフェイスを取得するために、引数付きのコンストラクタを追加している。これは周辺機器側からタートルへアクセスするのに必要である。また、attach時にTurtle内のComputerのアクセスインターフェイスを取得している。周辺機器ブロックと違い、アップグレード周辺機器に接続するのは装着されたTurtleだけなので、それらは単なるメンバ変数に保存している。 周辺機器のメソッドとして、[[周辺機器ブロック追加Mod>Modding/Peripheral]]のサンプルと同様の"test"と、Turtleの座標を取得する"getPosition"を実装している。getPositionは引数にtrueを指定して呼ばれた時は座標を文字列にして返し、それ以外のときは座標を3つの数値で返す(サンプルではあるが、GPSから考えればチート性能なメソッドである)。
ComputerCraftにTurtleアップグレードを追加する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-]] -[[ComputerCraft Wiki: Turtle Upgrade IDs>http://www.computercraft.info/wiki/index.php?title=Turtle_Upgrade_IDs]] -[[Minecraft Forge: Tutorials>http://www.minecraftforge.net/wiki/Category:Tutorials]] 執筆時のバージョン: -ComputerCraft 1.53 for Minecraft 1.5.2 ---- #contents ---- *Turtleアップグレード追加Modの概要 Turtleアップグレードとは、Digging TurtleやCrafty Turtleのように、Turtleにアイテムやブロックを装着(クラフト)することによって機能を追加することができるシステムである。 **アップグレードの実装 TurtleアップグレードはITurtleUpgradeインターフェイスの実装クラスとして機能を実装し、その実装クラスをComputerCraftに登録することによってTurtleに装着できるようになる。機能追加に関するAPIも用意されているため、簡単に作ることができる。 **アップグレードのタイプ Turtleアップグレードには以下の2タイプがある。 -[[turtle.digやturtle.attack>API/Turtle]]で作動する&bold(){Tool}タイプ(例:ダイヤシャベルでDigging Turtle) -[[Peripheral API>API/Peripheral]]で作動する&bold(){Peripheral}タイプ(例:作業台でCrafty Turtle) Turtleアップグレードを製作するときは、どちらか一方のタイプを選択する必要がある。今のところ1つのTurtleには、1つのToolタイプと1つのPeripheralタイプ、または2つのPeripheralタイプを装着することができる(例:ダイヤクワ(Tool)とWireless Modem(Peripheral)でWireless Farming Turtle)。 **アップグレードID Turtleアップグレードには他のTurtleアップグレードと重複しないID番号を割り当てる必要がある。Mod製作者が割り当て可能なIDの範囲は【-1.52】では64~255、【1.53-】では64~32767である。既に配布されているModが使用しているTurtleアップグレードIDは[[ComputerCraft Wiki>http://www.computercraft.info/wiki/index.php?title=Turtle_Upgrade_IDs]]で確認することができる。 *基本的なTurtleアップグレード追加Modの例 ToolタイプとPeripheralタイプのTurtleアップグレードを追加する。 このサンプルは以下の4クラスからなる。 -BasicUpgrades -TurtleBasicTool -TurtleBasicPeripheral -PeripheralTurtleBasicPeripheral 簡略化のため[[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]]は利用していない。 なお、このサンプルmodの前提modは【MinecraftForge】と【ComputerCraft】である。 **BasicUpgrades.java Modのメインクラス。@ModアノテーションによりForgeModLoaderにロードされる。 #highlight(java){{ package sample.upgrade; import net.minecraftforge.common.Configuration; import net.minecraftforge.common.Property; import cpw.mods.fml.common.Loader; 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 dan200.turtle.api.TurtleAPI; @Mod(modid="BasicUpgrades", name="BasicUpgrades", version="0.0.0", dependencies="after:CCTurtle") @NetworkMod(clientSideRequired=true, serverSideRequired=false) public class BasicUpgrades { public static int basicToolUpgradeID; public static int basicPeripheralUpgradeID; @Mod.PreInit public void preInit(FMLPreInitializationEvent event) { Property Prop; Configuration cfg = new Configuration(event.getSuggestedConfigurationFile()); cfg.load(); Prop = cfg.get("upgrade", "basicToolUpgradeID", 110); basicToolUpgradeID = Prop.getInt(); Prop = cfg.get("upgrade", "basicPeripheralUpgradeID", 111); basicPeripheralUpgradeID = Prop.getInt(); cfg.save(); } @Mod.Init public void init(FMLInitializationEvent event) { TurtleAPI.registerUpgrade(new TurtleBasicTool()); TurtleAPI.registerUpgrade(new TurtleBasicPeripheral()); } } }} @Modアノテーションを付加したクラスがForge Mod Loaderにロードされる。ここでModの情報も登録している。特筆すべきは&bold(){dependencies="after:CCTurtle"}という値で、これはこのModをComputerCraftよりも後に読み込ませる効果がある。 @Mod.PreInitアノテーションを付加したメソッド&bold(){preInit}(@Mod.Initメソッドの前に呼び出される)でコンフィグファイルを読み込み、TurtleアップグレードIDのブロックIDを取得している。ToolアップグレードIDのデフォルト値は&bold(){110}、PeripheralアップグレードIDのデフォルト値は&bold(){111}。 @Mod.Initアノテーションを付加したメソッド&bold(){init}(初期化時に呼び出される)でComputerCraftにTurtleアップグレードを登録している。TurtleアップブレードのクラスをTurtleAPI.registerUpgrade()で登録することにより、そのTurtleアップグレードがゲーム中で使用可能になる。 **TurtleBasicTool.java ITurtleUpgradeの実装クラスでToolタイプのTurtleアップグレードを実装している。このクラスで、アップグレードをTurtleに装着するためのアイテム(装着レシピはComputerCraftによる自動追加)や、装着後の外観、採掘・攻撃時の動作などを指定することができる。 このサンプルでは、簡単な採掘と攻撃ができるようになっている。 #highlight(java){{ package sample.upgrade; import java.util.ArrayList; import java.util.Iterator; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.Facing; import net.minecraft.util.Icon; import net.minecraft.util.Vec3; import net.minecraft.world.World; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.ITurtleUpgrade; import dan200.turtle.api.TurtleSide; import dan200.turtle.api.TurtleUpgradeType; import dan200.turtle.api.TurtleVerb; public class TurtleBasicTool implements ITurtleUpgrade { public ItemStack upgradeItem = new ItemStack(Item.pickaxeGold); @Override public int getUpgradeID() { return BasicUpgrades.basicToolUpgradeID; } @Override public String getAdjective() { return "Tool"; } @Override public TurtleUpgradeType getType() { return TurtleUpgradeType.Tool; } @Override public ItemStack getCraftingItem() { return upgradeItem; } @Override public boolean isSecret() { return false; } @Override public IHostedPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) { return null; } @Override public boolean useTool(ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, int direction) { switch( verb ) { case Dig: return dig(turtle, direction); case Attack: return attack(turtle, direction); } return false; } private boolean dig(ITurtleAccess turtle, int dir) { World world = turtle.getWorld(); Vec3 position = turtle.getPosition(); if (position == null) { return false; } int newX = (int)position.xCoord + Facing.offsetsXForSide[dir]; int newY = (int)position.yCoord + Facing.offsetsYForSide[dir]; int newZ = (int)position.zCoord + Facing.offsetsZForSide[dir]; if ( (newY < 0) || (newY >= world.getHeight()) ) { return false; } int blockID = world.getBlockId(newX, newY, newZ); Block block = Block.blocksList[blockID]; if ( (blockID == 0) || (blockID == Block.bedrock.blockID) || (block.getBlockHardness(world, newX, newY, newZ) <= -1.0F) ) { return false; } int matadata = world.getBlockMetadata(newX, newY, newZ); ArrayList items = block.getBlockDropped(world, newX, newY, newZ, matadata, 0); Iterator it = items.iterator(); while (it.hasNext()) { ItemStack item = (ItemStack)it.next(); if ( !turtle.storeItemStack(item) ) { int[] oppositeSide = { 1, 0, 3, 2, 5, 4 }; if ( !turtle.dropItemStack(item, oppositeSide[turtle.getFacingDir()]) ) { turtle.dropItemStack(item, turtle.getFacingDir()); } } } world.playAuxSFX(2001, newX, newY, newZ, blockID + matadata * 4096); world.setBlock(newX, newY, newZ, 0, 0, 3); return true; } private boolean attack(ITurtleAccess turtle, int dir) { return turtle.attackWithItemStack(new ItemStack(Item.swordDiamond), dir, 2.0F); } @Override public Icon getIcon(ITurtleAccess turtle, TurtleSide side) { return upgradeItem.getIconIndex(); } } }} TurtleアップグレードIDはgetUpgradeIDの戻り値で指定する。このサンプルでは前述の@MODクラスBasicUpgradesのメンバー変数から取得して指定している。アップグレードのタイプはenum TurtleUpgradeTypeの列挙子でToolを指定。装着したTurtleに付く形容詞は"Tool"を指定(つまり"Tool Turtle"になる)。クラフトに必要なアイテムと装着したアップグレードの外観は金のツルハシ。Toolタイプなので無用なcreatePeripheralではnullを返す。 Toolタイプの本領はuseToolによって発揮される。このサンプルではverbの種類(DigかAttackか)で分岐させた後、それぞれ別のメンバー関数(digとattack)に処理させている。 -dig Turtleに採掘させる場合、採掘に必要な処理そのものを書く必要がある。 まず、useToolから得たITurtleAccess turtleによりTurtleの座標を得て、その座標と採掘する方向dirから採掘すべきブロックの座標と種類、メタデータを取得する。次に、採掘すべきブロックが採掘できるか(高度、種類)を調べる。採掘可能だった場合は採掘して得られるアイテムを取得し、スロットに入りきらなかった場合はドロップする。最後に採掘の効果音を鳴らし、採掘したブロックを消す(空気ブロックにする)。 -attack 採掘処理が難しい一方で、攻撃は専用メソッドが用意されているため簡単である。このサンプルではダイヤソードの2倍の攻撃力14(ハート7個分)でdir方向を攻撃する。 ちなみに、それぞれのverdは単にTurtle側のturtle.dig()とturtle.attack()で呼び出されるというだけで、必ずしもTurtleが採掘や攻撃を行わなければならないという訳ではない。 **TurtleBasicPeripheral.java ITurtleUpgradeの実装クラスでPeripheralタイプのTurtleアップグレードを実装している。 #highlight(java){{ package sample.upgrade; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.util.Icon; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.ITurtleUpgrade; import dan200.turtle.api.TurtleSide; import dan200.turtle.api.TurtleUpgradeType; import dan200.turtle.api.TurtleVerb; public class TurtleBasicPeripheral implements ITurtleUpgrade { public ItemStack upgradeItem = new ItemStack(Block.stone, 1, 0); @Override public int getUpgradeID() { return BasicUpgrades.basicPeripheralUpgradeID; } @Override public String getAdjective() { return "Peripheral"; } @Override public TurtleUpgradeType getType() { return TurtleUpgradeType.Peripheral; } @Override public ItemStack getCraftingItem() { return upgradeItem; } @Override public boolean isSecret() { return false; } @Override public IHostedPeripheral createPeripheral(ITurtleAccess turtle, TurtleSide side) { return new PeripheralTurtleBasicPeripheral(turtle, side); } @Override public boolean useTool(ITurtleAccess turtle, TurtleSide side, TurtleVerb verb, int direction) { return false; } @Override public Icon getIcon(ITurtleAccess turtle, TurtleSide side) { return Block.stoneSingleSlab.getBlockTextureFromSide(0); } } }} TurtleアップグレードIDはgetUpgradeIDの戻り値で指定する。このサンプルでは前述の@MODクラスBasicUpgradesのメンバー変数から取得して指定している。アップグレードのタイプはenum TurtleUpgradeTypeの列挙子でPeripheralを指定。装着したTurtleに付く形容詞は"Peripheral"を指定(つまり"Peripheral Turtle"になる)。クラフトに必要なアイテムは石ブロック。装着したアップグレードの外観は石ハーフブロックの下面。 Peripheralタイプなので、createPeripheralでは周辺機器の機能を実装したIHostedPeripheralの実装クラスのインスタンスを返す。このサンプルでは、後述のPeripheralTurtleBasicPeripheralのインスタンスを返している。ToolタイプではないのでuseToolは呼び出されない。 **PeripheralTurtleBasicPeripheral.java IHostedPeripheralの実装クラスでPeripheralタイプのアップグレードの周辺機器としての動作を実装している。IHostedPeripheralはIPeripheralのサブインターフェイスである。[[周辺機器ブロック追加Mod>Modding/Peripheral]]も参照のこと。 #highlight(java){{ package sample.upgrade; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.Vec3; import dan200.computer.api.IComputerAccess; import dan200.computer.api.IHostedPeripheral; import dan200.turtle.api.ITurtleAccess; import dan200.turtle.api.TurtleSide; public class PeripheralTurtleBasicPeripheral implements IHostedPeripheral { private ITurtleAccess m_turtle; private IComputerAccess m_computer; private TurtleSide m_side; PeripheralTurtleBasicPeripheral(ITurtleAccess turtle, TurtleSide side) { m_turtle = turtle; m_side = side; } @Override public String getType() { return "turtlebasic"; } @Override public String[] getMethodNames() { return new String[] { "test", "getPosition" }; } @Override public Object[] callMethod( IComputerAccess computer, int method, Object[] arguments ) throws Exception { switch( method ) { case 0: // test if( arguments.length < 1 ) { throw new Exception("Expected argument"); } return new Object[] { arguments[0] }; case 1: //getPosition Vec3 pos = m_turtle.getPosition(); if( arguments.length > 0 && arguments[0] instanceof Boolean && true == (Boolean)arguments[0]) { return new Object[] { "Position: " + (int)pos.xCoord + ", " + (int)pos.yCoord + ", " + (int)pos.zCoord }; } return new Object[] { Integer.valueOf((int)pos.xCoord), Integer.valueOf((int)pos.yCoord), Integer.valueOf((int)pos.zCoord) }; } return null; } @Override public boolean canAttachToSide(int side) { return true; } @Override public void attach( IComputerAccess computer) { m_computer = computer; System.out.printf("[TurtleBasicPeripheral] Attached to Computer #%d (side: %s)\n", m_computer.getID(), m_computer.getAttachmentName() ); } @Override public void detach( IComputerAccess computer ) { System.out.printf("[TurtleBasicPeripheral] Detached from Computer #%d\n", computer.getID() ); } @Override public void update() { } @Override public void readFromNBT(NBTTagCompound nbttagcompound) { } @Override public void writeToNBT(NBTTagCompound nbttagcompound) { } } }} [[周辺機器ブロック追加Mod>Modding/Peripheral]]と似たような構成になっているが、以下のような点が違う。 -attachはTurtle起動時、detachはattach後のTurtle破壊時に呼び出される(Turtleアップグレードの特徴) -attach後に毎Tick呼び出されるupdateが追加されている(IHostedPeripheralの特徴) -NBTへデータを読み書きするメソッドが追加されている(IHostedPeripheralの特徴) このサンプルではタートルへのアクセスインターフェイスを取得するために、引数付きのコンストラクタを追加している。これは周辺機器側からタートルへアクセスするのに必要である。また、attach時にTurtle内のComputerのアクセスインターフェイスを取得している。周辺機器ブロックと違い、アップグレード周辺機器に接続するのは装着されたTurtleだけなので、それらは単なるメンバ変数に保存している。 周辺機器のメソッドとして、[[周辺機器ブロック追加Mod>Modding/Peripheral]]のサンプルと同様の"test"と、Turtleの座標を取得する"getPosition"を実装している。getPositionは引数にtrueを指定して呼ばれた時は座標を文字列にして返し、それ以外のときは座標を3つの数値で返す(サンプルではあるが、GPSから考えればチート性能なメソッドである)。

表示オプション

横に並べて表示:
変化行の前後のみ表示: