1行目: | 1行目: | ||
このページは[http://www.minecraftforge.net/wiki/ Minecraft Forge Wiki]の[http://www.minecraftforge.net/wiki/How_to_use_NBT_Tag_Compound How to use NBT Tag Compound]の訳です。 | このページは[http://www.minecraftforge.net/wiki/ Minecraft Forge Wiki]の[http://www.minecraftforge.net/wiki/How_to_use_NBT_Tag_Compound How to use NBT Tag Compound]の訳です。 | ||
− | |||
=NBT Tag Compoundの使い方= | =NBT Tag Compoundの使い方= | ||
==最終的な目標== | ==最終的な目標== | ||
− | + | ||
− | + | 最後にブロックを右クリックした5人のプレイヤーを記録する "last 5 visitors"ブロックを作成します | |
− | Basic blocks | + | |
+ | ==前提となる知識== | ||
+ | |||
+ | [[Basic blocks]] | ||
==NBTとは?== | ==NBTとは?== | ||
− | + | NBTとは、Minecraftのマップ保存の為にNotchが作成したフォーマットです。ノードを基にしたファイルで、regionファイル、player.datファイル、level.datファイルに使われています。 | |
+ | |||
+ | バイナリだということを除けば、NBTの構造はとてもXMLに似ていると考えることができます。 | ||
− | |||
どのNBTファイルも必ず"Tag_Compound"という種類のルートタグから始まっていて、それがこのチュートリアルの名前になっています。1つのTag_Compoundは他のノードをその中に保持することができます。そのルートタグは通常名前を持ちません。 | どのNBTファイルも必ず"Tag_Compound"という種類のルートタグから始まっていて、それがこのチュートリアルの名前になっています。1つのTag_Compoundは他のノードをその中に保持することができます。そのルートタグは通常名前を持ちません。 | ||
==NBTを使う理由== | ==NBTを使う理由== | ||
− | + | NBTはブロックやアイテムのデータ/メタデータに保存出来ないものを保存するのにとても優れています。例えば、チェストの全アイテムの情報は4ビットのメタデータには保存出来ません。でも、NBTなら実質無限なのです。ただ、HDDの容量が実に増えているとは言え、大量に自然に現れるブロックにNBTを使用してはいけません。 | |
− | + | ||
− | + | また、NBTはアイテムにも便利です。例えば、本は作者と内容を保存するためにNBTを使用しています。 | |
+ | |||
+ | ===MinecraftのどこにNBTが使われているでしょう?=== | ||
+ | |||
+ | *看板 | ||
+ | *本 | ||
+ | *インベントリを持つ全てのブロック(かまど、チェスト、などなど) | ||
+ | |||
+ | ===タグの種類=== | ||
+ | |||
+ | NBTには12種類ものタグがあり、様々なデータが格納可能です: | ||
+ | {| | ||
+ | |'''ID''' | ||
+ | |'''名前''' | ||
+ | |'''解説''' | ||
+ | |- | ||
+ | |0 | ||
+ | |TAG_End | ||
+ | |Compound Tagの終わり。通常見ることはない。 | ||
+ | |- | ||
+ | |1 | ||
+ | |TAG_Byte | ||
+ | |1バイトのデータを含むタグ | ||
+ | |- | ||
+ | |2 | ||
+ | |TAG_Short | ||
+ | |1つのshort(数値)を含むタグ | ||
+ | |- | ||
+ | |3 | ||
+ | |TAG_Int | ||
+ | |1つのintegerを含むタグ | ||
+ | |- | ||
+ | |4 | ||
+ | |TAG_Long | ||
+ | |1つのlongを含むタグ | ||
+ | |- | ||
+ | |5 | ||
+ | |TAG_Float | ||
+ | |1つのfloatを含むタグ | ||
+ | |- | ||
+ | |6 | ||
+ | |TAG_Double | ||
+ | |1つのdoubleを含むタグ | ||
+ | |- | ||
+ | |7 | ||
+ | |TAG_Byte_Array | ||
+ | |byteの配列を含むタグ | ||
+ | |- | ||
+ | |8 | ||
+ | |TAG_String | ||
+ | |文字列を含むタグ | ||
+ | |- | ||
+ | |9 | ||
+ | |TAG_List | ||
+ | |同じ種類の無名タグのリスト | ||
+ | |- | ||
+ | |10 | ||
+ | |TAG_Compound | ||
+ | |名前付きタグのリスト。それぞれのNBTファイルの起点。他のCompoundを含むことが出来る。 | ||
+ | |- | ||
+ | |11 | ||
+ | |TAG_Int_Array | ||
+ | |integerの配列 | ||
+ | |- | ||
+ | |} | ||
+ | |||
+ | ''MinecraftCoalitionのNBTに関する情報はこのページの「参照」以下より参照してください。'' | ||
− | + | ===ブロックのクラスを書く=== | |
− | |||
− | |||
− | |||
− | + | もし作っているのがアイテムなら、ItemStackからCompound Tagを取得出来ます。それについてのチュートリアルを作成する必要があるでしょう。でも今はブロックで忙しいのです。 | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | NBTの値を保存するためにはTileEntityというものが必要です。TileEntityは基本的にブロックと繋がったエンティティで、ブロックの情報を保存するために使われます。 | |
− | + | 最初に、コンストラクタを作ります。このクラスはBlockContainerを継承することに注意してください。 | |
− | |||
+ | <source lang="java"> | ||
public BlockVisitor(int id) { | public BlockVisitor(int id) { | ||
super(id, 35, Material.circuits); | super(id, 35, Material.circuits); | ||
// TODO Auto-generated constructor stub | // TODO Auto-generated constructor stub | ||
} | } | ||
− | + | </source> | |
− | + | これについては説明する必要は無いでしょう。 | |
+ | |||
+ | 次は、右クリックを検知するメソッドです。 | ||
+ | <source lang="java"> | ||
public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) | public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) | ||
{ | { | ||
63行目: | 118行目: | ||
return true; | return true; | ||
} | } | ||
− | + | </source> | |
+ | |||
+ | 行ごとに見て行きましょう。 | ||
+ | <source lang="java"> | ||
if(!world.isRemote) | if(!world.isRemote) | ||
− | + | </source> | |
+ | この行は、メソッドを呼び出しているのがサーバーかクライアントかを確認します。isRemoteはクライアントではtrueを返します。これは、1.2.5以降ではシングルでもローカルサーバー上で実行されているためです。つまり、これはサーバー/クライアントを検知する簡単な方法なのです。 | ||
+ | |||
+ | <source lang="java"> | ||
TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); | TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); | ||
− | + | </source> | |
+ | この行では変数tにgetBlockTileEntityメソッドを用いてワールドからTileEntityを取得します。par2、3、4はx、y、z座標を表します。 | ||
+ | TileEntityVisitorにキャストしていることに注意してください。 | ||
+ | |||
+ | <source lang="java"> | ||
t.processActivate(par5EntityPlayer, world); | t.processActivate(par5EntityPlayer, world); | ||
− | + | </source> | |
− | + | これは、登録と表示のためにTileEntityに設けた、processActivateというメソッドを呼び出しています。引数はプレイヤーとワールドです。 | |
+ | |||
+ | また、MinecraftにTileEntityを使うことを知らせるためにメソッドを追加する必要があります: | ||
+ | <source lang="java"> | ||
public boolean hasTileEntity(int metadata) | public boolean hasTileEntity(int metadata) | ||
{ | { | ||
return true; | return true; | ||
} | } | ||
− | + | </source> | |
+ | ブロックのファイルの最後のメソッドはcreateNewTileEntity()です。これは非常に単純で、TileEntityVisitorの新しいインスタンスを返すのみとなっています: | ||
+ | <source lang="java"> | ||
public TileEntity createNewTileEntity(World par1World) | public TileEntity createNewTileEntity(World par1World) | ||
{ | { | ||
87行目: | 157行目: | ||
} | } | ||
} | } | ||
− | + | </source> | |
+ | これでブロックのファイルについては終わりました。TileEntityに移りましょう。 | ||
− | + | ===TileEntityを作る=== | |
− | + | TileEntityはコンストラクタを必要としません。実際、最初にするのは訪問者を保持する変数の定義です: | |
+ | <source lang="java"> | ||
String visitor1="none"; | String visitor1="none"; | ||
String visitor2="none"; | String visitor2="none"; | ||
97行目: | 169行目: | ||
String visitor4="none"; | String visitor4="none"; | ||
String visitor5="none"; | String visitor5="none"; | ||
− | + | </source> | |
− | + | 配列は使いません。何か問題でも? | |
+ | |||
+ | 次はNBT Tag Compoundから情報を読み込むメソッドを書きます: | ||
+ | <source lang="java"> | ||
@Override | @Override | ||
public void readFromNBT(NBTTagCompound nbt) | public void readFromNBT(NBTTagCompound nbt) | ||
109行目: | 184行目: | ||
this.visitor5 = nbt.getString("visitor5"); | this.visitor5 = nbt.getString("visitor5"); | ||
} | } | ||
− | + | </source> | |
− | + | お分かりの通り、読み込みのためにNBTTagComponundを使います。コードについては自明です。注意として、super.readFromNBT(TagCompound);の実行を忘れないでください。幾つもの情報をTileEntity自身が保存し、読み込んでいるからです。 | |
+ | |||
+ | 次のメソッドはNBTへの保存です: | ||
+ | <source lang="java"> | ||
@Override | @Override | ||
public void writeToNBT(NBTTagCompound nbt) | public void writeToNBT(NBTTagCompound nbt) | ||
121行目: | 199行目: | ||
nbt.setString("visitor5", visitor5); | nbt.setString("visitor5", visitor5); | ||
} | } | ||
− | + | </source> | |
− | + | このコードもまた自明です。 | |
+ | |||
+ | 最後のコードはブロックの方で呼び出されていたメソッドです。 | ||
+ | <source lang="java"> | ||
public void processActivate(EntityPlayer par5EntityPlayer, World world) { | public void processActivate(EntityPlayer par5EntityPlayer, World world) { | ||
if(!visitor1.equals(par5EntityPlayer.getEntityName())) | if(!visitor1.equals(par5EntityPlayer.getEntityName())) | ||
136行目: | 217行目: | ||
world.notifyBlockChange(xCoord, yCoord, zCoord, 2); | world.notifyBlockChange(xCoord, yCoord, zCoord, 2); | ||
} | } | ||
− | + | </source> | |
+ | |||
+ | これには幾らかの説明が必要でしょう: | ||
+ | <source lang="java"> | ||
if(!visitor1.equals(par5EntityPlayer.getEntityName())) | if(!visitor1.equals(par5EntityPlayer.getEntityName())) | ||
− | + | </source> | |
+ | これは、同じ訪問者を2度登録させないためです。 | ||
+ | |||
+ | <source lang="java"> | ||
visitor5=visitor4; | visitor5=visitor4; | ||
visitor4=visitor3; | visitor4=visitor3; | ||
144行目: | 231行目: | ||
visitor2=visitor1; | visitor2=visitor1; | ||
visitor1=par5EntityPlayer.getEntityName(); | visitor1=par5EntityPlayer.getEntityName(); | ||
− | + | </source> | |
+ | これは訪問者一覧を入れ替えます。 | ||
+ | |||
+ | <source lang="java"> | ||
world.notifyBlockChange(xCoord, yCoord, zCoord, 2); | world.notifyBlockChange(xCoord, yCoord, zCoord, 2); | ||
− | + | </source> | |
+ | 安全のためです。このメソッドはワールドに周囲のブロックを更新することを伝えます。チャットに訪問者を表示していることにも注意してください。 | ||
− | + | ===全てのコード=== | |
− | VisitorBlock.java( | + | VisitorBlock.java(メインのコード) |
+ | <source lang="java"> | ||
package com.generic.tutorial.nbt.block; | package com.generic.tutorial.nbt.block; | ||
166行目: | 258行目: | ||
@NetworkMod(clientSideRequired=true, serverSideRequired=false) | @NetworkMod(clientSideRequired=true, serverSideRequired=false) | ||
public class VisitorBlock { | public class VisitorBlock { | ||
− | + | @Instance("VisitorBlock") | |
− | + | VisitorBlock instance; | |
− | + | BlockVisitor visitor; | |
− | + | int blockID=200; | |
− | + | @PreInit | |
− | + | public void preInit(FMLPreInitializationEvent event) | |
− | + | { | |
− | + | ||
− | + | } | |
− | + | @Init | |
− | + | public void load(FMLInitializationEvent event) { | |
− | + | visitor = new BlockVisitor(blockID); | |
− | + | GameRegistry.registerBlock(visitor); | |
− | + | GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock"); | |
− | + | GameRegistry.addRecipe(new ItemStack(visitor, 1), "###", "#%#", "###", '#', Item.redstone, '%', Item.paper); | |
− | + | } | |
} | } | ||
− | BlockVisitor.java ( | + | |
+ | </source> | ||
+ | |||
+ | BlockVisitor.java (ブロックのクラス) | ||
+ | |||
+ | <source lang="java"> | ||
package com.generic.tutorial.nbt.block; | package com.generic.tutorial.nbt.block; | ||
195行目: | 292行目: | ||
public class BlockVisitor extends BlockContainer { | public class BlockVisitor extends BlockContainer { | ||
− | + | public BlockVisitor(int id) { | |
− | + | super(id, 35, Material.circuits); | |
− | + | // TODO Auto-generated constructor stub | |
− | + | } | |
− | + | public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) | |
{ | { | ||
− | + | if(!world.isRemote) | |
− | + | { | |
− | + | TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); | |
− | + | t.processActivate(par5EntityPlayer, world); | |
− | + | } | |
− | + | return true; | |
} | } | ||
− | + | public boolean hasTileEntity(int metadata) | |
{ | { | ||
return true; | return true; | ||
} | } | ||
− | + | @Override | |
− | + | public TileEntity createNewTileEntity(World par1World) | |
{ | { | ||
try | try | ||
226行目: | 323行目: | ||
} | } | ||
+ | </source> | ||
+ | |||
TileEntityVisitor.java | TileEntityVisitor.java | ||
+ | <source lang="java"> | ||
package com.generic.tutorial.nbt.block; | package com.generic.tutorial.nbt.block; | ||
233行目: | 333行目: | ||
public class TileEntityVisitor extends TileEntity{ | public class TileEntityVisitor extends TileEntity{ | ||
− | + | String visitor1="none"; | |
− | + | String visitor2="none"; | |
− | + | String visitor3="none"; | |
− | + | String visitor4="none"; | |
− | + | String visitor5="none"; | |
− | + | public void processActivate(EntityPlayer par5EntityPlayer, World world) { | |
− | + | if(!visitor1.equals(par5EntityPlayer.getEntityName())) | |
− | + | { | |
− | + | visitor5=visitor4; | |
− | + | visitor4=visitor3; | |
− | + | visitor3=visitor2; | |
− | + | visitor2=visitor1; | |
− | + | visitor1=par5EntityPlayer.getEntityName(); | |
− | + | } | |
− | + | //System.out.println("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); | |
par5EntityPlayer.addChatMessage("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); | par5EntityPlayer.addChatMessage("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); | ||
− | + | world.notifyBlockChange(xCoord, yCoord, zCoord, 2); | |
− | + | } | |
− | + | ||
− | + | @Override | |
− | + | public void readFromNBT(NBTTagCompound nbt) | |
{ | { | ||
super.readFromNBT(nbt); | super.readFromNBT(nbt); | ||
266行目: | 366行目: | ||
public void writeToNBT(NBTTagCompound nbt) | public void writeToNBT(NBTTagCompound nbt) | ||
{ | { | ||
− | + | super.writeToNBT(nbt); | |
− | + | nbt.setString("visitor1", visitor1); | |
nbt.setString("visitor2", visitor2); | nbt.setString("visitor2", visitor2); | ||
nbt.setString("visitor3", visitor3); | nbt.setString("visitor3", visitor3); | ||
275行目: | 375行目: | ||
} | } | ||
+ | </source> | ||
− | + | ===注意事項=== | |
− | + | Forge(訳注:これ自体はFML)を使ってTileEntityを登録する必要があります: | |
+ | <source lang="java"> | ||
GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock"); | GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock"); | ||
− | + | </source> | |
+ | |||
+ | ===参考== | ||
− | NBT | + | [http://wiki.vg/NBT Minecraft CoalitionのNBTのページ] |
− |
2012年12月13日 (木) 23:04時点における最新版
このページはMinecraft Forge WikiのHow to use NBT Tag Compoundの訳です。
目次
NBT Tag Compoundの使い方[編集]
最終的な目標[編集]
最後にブロックを右クリックした5人のプレイヤーを記録する "last 5 visitors"ブロックを作成します
前提となる知識[編集]
NBTとは?[編集]
NBTとは、Minecraftのマップ保存の為にNotchが作成したフォーマットです。ノードを基にしたファイルで、regionファイル、player.datファイル、level.datファイルに使われています。
バイナリだということを除けば、NBTの構造はとてもXMLに似ていると考えることができます。
どのNBTファイルも必ず"Tag_Compound"という種類のルートタグから始まっていて、それがこのチュートリアルの名前になっています。1つのTag_Compoundは他のノードをその中に保持することができます。そのルートタグは通常名前を持ちません。
NBTを使う理由[編集]
NBTはブロックやアイテムのデータ/メタデータに保存出来ないものを保存するのにとても優れています。例えば、チェストの全アイテムの情報は4ビットのメタデータには保存出来ません。でも、NBTなら実質無限なのです。ただ、HDDの容量が実に増えているとは言え、大量に自然に現れるブロックにNBTを使用してはいけません。
また、NBTはアイテムにも便利です。例えば、本は作者と内容を保存するためにNBTを使用しています。
MinecraftのどこにNBTが使われているでしょう?[編集]
- 看板
- 本
- インベントリを持つ全てのブロック(かまど、チェスト、などなど)
タグの種類[編集]
NBTには12種類ものタグがあり、様々なデータが格納可能です:
ID | 名前 | 解説 |
0 | TAG_End | Compound Tagの終わり。通常見ることはない。 |
1 | TAG_Byte | 1バイトのデータを含むタグ |
2 | TAG_Short | 1つのshort(数値)を含むタグ |
3 | TAG_Int | 1つのintegerを含むタグ |
4 | TAG_Long | 1つのlongを含むタグ |
5 | TAG_Float | 1つのfloatを含むタグ |
6 | TAG_Double | 1つのdoubleを含むタグ |
7 | TAG_Byte_Array | byteの配列を含むタグ |
8 | TAG_String | 文字列を含むタグ |
9 | TAG_List | 同じ種類の無名タグのリスト |
10 | TAG_Compound | 名前付きタグのリスト。それぞれのNBTファイルの起点。他のCompoundを含むことが出来る。 |
11 | TAG_Int_Array | integerの配列 |
MinecraftCoalitionのNBTに関する情報はこのページの「参照」以下より参照してください。
ブロックのクラスを書く[編集]
もし作っているのがアイテムなら、ItemStackからCompound Tagを取得出来ます。それについてのチュートリアルを作成する必要があるでしょう。でも今はブロックで忙しいのです。
NBTの値を保存するためにはTileEntityというものが必要です。TileEntityは基本的にブロックと繋がったエンティティで、ブロックの情報を保存するために使われます。
最初に、コンストラクタを作ります。このクラスはBlockContainerを継承することに注意してください。
public BlockVisitor(int id) { super(id, 35, Material.circuits); // TODO Auto-generated constructor stub }
これについては説明する必要は無いでしょう。
次は、右クリックを検知するメソッドです。
public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { if(!world.isRemote) { TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); t.processActivate(par5EntityPlayer, world); } return true; }
行ごとに見て行きましょう。
if(!world.isRemote)
この行は、メソッドを呼び出しているのがサーバーかクライアントかを確認します。isRemoteはクライアントではtrueを返します。これは、1.2.5以降ではシングルでもローカルサーバー上で実行されているためです。つまり、これはサーバー/クライアントを検知する簡単な方法なのです。
TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4);
この行では変数tにgetBlockTileEntityメソッドを用いてワールドからTileEntityを取得します。par2、3、4はx、y、z座標を表します。 TileEntityVisitorにキャストしていることに注意してください。
t.processActivate(par5EntityPlayer, world);
これは、登録と表示のためにTileEntityに設けた、processActivateというメソッドを呼び出しています。引数はプレイヤーとワールドです。
また、MinecraftにTileEntityを使うことを知らせるためにメソッドを追加する必要があります:
public boolean hasTileEntity(int metadata) { return true; }
ブロックのファイルの最後のメソッドはcreateNewTileEntity()です。これは非常に単純で、TileEntityVisitorの新しいインスタンスを返すのみとなっています:
public TileEntity createNewTileEntity(World par1World) { try { return new TileEntityVisitor(); } catch (Exception var3) { throw new RuntimeException(var3); } }
これでブロックのファイルについては終わりました。TileEntityに移りましょう。
TileEntityを作る[編集]
TileEntityはコンストラクタを必要としません。実際、最初にするのは訪問者を保持する変数の定義です:
String visitor1="none"; String visitor2="none"; String visitor3="none"; String visitor4="none"; String visitor5="none";
配列は使いません。何か問題でも?
次はNBT Tag Compoundから情報を読み込むメソッドを書きます:
@Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.visitor1 = nbt.getString("visitor1"); this.visitor2 = nbt.getString("visitor2"); this.visitor3 = nbt.getString("visitor3"); this.visitor4 = nbt.getString("visitor4"); this.visitor5 = nbt.getString("visitor5"); }
お分かりの通り、読み込みのためにNBTTagComponundを使います。コードについては自明です。注意として、super.readFromNBT(TagCompound);の実行を忘れないでください。幾つもの情報をTileEntity自身が保存し、読み込んでいるからです。
次のメソッドはNBTへの保存です:
@Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setString("visitor1", visitor1); nbt.setString("visitor2", visitor2); nbt.setString("visitor3", visitor3); nbt.setString("visitor4", visitor4); nbt.setString("visitor5", visitor5); }
このコードもまた自明です。
最後のコードはブロックの方で呼び出されていたメソッドです。
public void processActivate(EntityPlayer par5EntityPlayer, World world) { if(!visitor1.equals(par5EntityPlayer.getEntityName())) { visitor5=visitor4; visitor4=visitor3; visitor3=visitor2; visitor2=visitor1; visitor1=par5EntityPlayer.getEntityName(); } //System.out.println("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); par5EntityPlayer.addChatMessage("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); world.notifyBlockChange(xCoord, yCoord, zCoord, 2); }
これには幾らかの説明が必要でしょう:
if(!visitor1.equals(par5EntityPlayer.getEntityName()))
これは、同じ訪問者を2度登録させないためです。
visitor5=visitor4; visitor4=visitor3; visitor3=visitor2; visitor2=visitor1; visitor1=par5EntityPlayer.getEntityName();
これは訪問者一覧を入れ替えます。
world.notifyBlockChange(xCoord, yCoord, zCoord, 2);
安全のためです。このメソッドはワールドに周囲のブロックを更新することを伝えます。チャットに訪問者を表示していることにも注意してください。
全てのコード[編集]
VisitorBlock.java(メインのコード)
package com.generic.tutorial.nbt.block; import net.minecraft.src.*; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.Init; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.Mod.PreInit; 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; @Mod(modid="VisitorBlock", name="VisitorBlock", version="0.0.1") @NetworkMod(clientSideRequired=true, serverSideRequired=false) public class VisitorBlock { @Instance("VisitorBlock") VisitorBlock instance; BlockVisitor visitor; int blockID=200; @PreInit public void preInit(FMLPreInitializationEvent event) { } @Init public void load(FMLInitializationEvent event) { visitor = new BlockVisitor(blockID); GameRegistry.registerBlock(visitor); GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock"); GameRegistry.addRecipe(new ItemStack(visitor, 1), "###", "#%#", "###", '#', Item.redstone, '%', Item.paper); } }
BlockVisitor.java (ブロックのクラス)
package com.generic.tutorial.nbt.block; import net.minecraft.src.Block; import net.minecraft.src.BlockContainer; import net.minecraft.src.EntityPlayer; import net.minecraft.src.Material; import net.minecraft.src.TileEntity; import net.minecraft.src.World; public class BlockVisitor extends BlockContainer { public BlockVisitor(int id) { super(id, 35, Material.circuits); // TODO Auto-generated constructor stub } public boolean onBlockActivated(World world, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9) { if(!world.isRemote) { TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); t.processActivate(par5EntityPlayer, world); } return true; } public boolean hasTileEntity(int metadata) { return true; } @Override public TileEntity createNewTileEntity(World par1World) { try { return new TileEntityVisitor(); } catch (Exception var3) { throw new RuntimeException(var3); } } }
TileEntityVisitor.java
package com.generic.tutorial.nbt.block; import net.minecraft.src.*; public class TileEntityVisitor extends TileEntity{ String visitor1="none"; String visitor2="none"; String visitor3="none"; String visitor4="none"; String visitor5="none"; public void processActivate(EntityPlayer par5EntityPlayer, World world) { if(!visitor1.equals(par5EntityPlayer.getEntityName())) { visitor5=visitor4; visitor4=visitor3; visitor3=visitor2; visitor2=visitor1; visitor1=par5EntityPlayer.getEntityName(); } //System.out.println("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); par5EntityPlayer.addChatMessage("Visitors: " + visitor1 + ", " + visitor2 + ", " + visitor3 + ", " + visitor4 + ", " + visitor5); world.notifyBlockChange(xCoord, yCoord, zCoord, 2); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); this.visitor1 = nbt.getString("visitor1"); this.visitor2 = nbt.getString("visitor2"); this.visitor3 = nbt.getString("visitor3"); this.visitor4 = nbt.getString("visitor4"); this.visitor5 = nbt.getString("visitor5"); } @Override public void writeToNBT(NBTTagCompound nbt) { super.writeToNBT(nbt); nbt.setString("visitor1", visitor1); nbt.setString("visitor2", visitor2); nbt.setString("visitor3", visitor3); nbt.setString("visitor4", visitor4); nbt.setString("visitor5", visitor5); } }
注意事項[編集]
Forge(訳注:これ自体はFML)を使ってTileEntityを登録する必要があります:
GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock");