提供: Minecraft Modding Wiki
移動先: 案内検索
(ページの作成:「このページは[http://www.minecraftforge.net/wiki/ Minecraft Forge Wiki]の[http://www.minecraftforge.net/wiki/How_to_use_NBT_Tag_Compound How to use NBT Tag Compou...」)
 
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]の訳です。
How to use NBT Tag Compound
+
翻訳はプログラミングやModdingに疎い人間がしています。訳語に不自然な点があれば訂正してください。
Contents [hide]
 
1 Goals
 
2 Prerequisites
 
3 What is NBT?
 
4 Why use NBT?
 
5 What is NBT used for in Minecraft?
 
6 Types of tags
 
7 Writing the block class
 
8 Making the TileEntity
 
9 All the code
 
10 Please note
 
11 Read more
 
Goals
 
  
Create a "last 5 visitors" block, that remembers the last 5 people to click on the block.
+
=NBT Tag Compoundの使い方=
  
Prerequisites
+
==最終的な目標==
 +
最後にブロックに右クリックをしたプレイヤーを記録する "last 5 visitors" Blockを作成します
 +
*前提となる知識
 +
Basic blocks
  
Basic blocks
+
==NBTとは?==
 +
 
 +
NBTとは、Minecraftのマップ保存の為にNotchが作成したフォーマットです。ノードをベースにしたファイル{node-based file}で、region files、player.dat files、level.dat filesに使われています。
  
What is NBT?
+
NBTの構造は、バイナリを除いて、XMLのようなビットと考えることができます。<br>
 +
どのNBTファイルも必ず"Tag_Compound"という種類のルートタグから始まっていて、それがこのチュートリアルの名前になっています。1つのTag_Compoundは他のノードをその中に保持することができます。そのルートタグは通常名前を持ちません。
  
NBT is the map format made by Notch for saving the Minecraft map. It is a node-based file format, used in region files, player.dat files, and level.dat files.
+
==NBTを使う理由==
You can think of the structure as a bit like XML, but in binary.
 
Any NBT file starts with a root tag. It is of the type "TAG_Compound", therefore the name of this tutorial. A Tag_Compound is a node capable of holding other nodes inside. The root tag normally does not have a name.
 
Why use NBT?
 
  
 
NBT is very good if you want to store data that cannot be stored in data/metadata of the block/item. For example, you cant save all the item information from a chest in a 4 bit metadata, so you use NBT, which is practically infinite big. Size of block on the hard drive does increase a lot, though, so dont use NBT in blocks appearing naturally in big quantities.
 
NBT is very good if you want to store data that cannot be stored in data/metadata of the block/item. For example, you cant save all the item information from a chest in a 4 bit metadata, so you use NBT, which is practically infinite big. Size of block on the hard drive does increase a lot, though, so dont use NBT in blocks appearing naturally in big quantities.

2012年10月29日 (月) 16:26時点における版

このページはMinecraft Forge WikiHow to use NBT Tag Compoundの訳です。 翻訳はプログラミングやModdingに疎い人間がしています。訳語に不自然な点があれば訂正してください。

NBT Tag Compoundの使い方

最終的な目標

最後にブロックに右クリックをしたプレイヤーを記録する "last 5 visitors" Blockを作成します

  • 前提となる知識

Basic blocks

NBTとは?

NBTとは、Minecraftのマップ保存の為にNotchが作成したフォーマットです。ノードをベースにしたファイル{node-based file}で、region files、player.dat files、level.dat filesに使われています。

NBTの構造は、バイナリを除いて、XMLのようなビットと考えることができます。
どのNBTファイルも必ず"Tag_Compound"という種類のルートタグから始まっていて、それがこのチュートリアルの名前になっています。1つのTag_Compoundは他のノードをその中に保持することができます。そのルートタグは通常名前を持ちません。

NBTを使う理由

NBT is very good if you want to store data that cannot be stored in data/metadata of the block/item. For example, you cant save all the item information from a chest in a 4 bit metadata, so you use NBT, which is practically infinite big. Size of block on the hard drive does increase a lot, though, so dont use NBT in blocks appearing naturally in big quantities. NBT may also be useful in items. For example, the book uses NBT to save the author and contents of itself. What is NBT used for in Minecraft?

Signs Books All blocks with an inventory(Furnace, Chest, etc...) Types of tags

There are 12 different types of tags, capable of storing different data: ID Name Description 0 TAG_End End of a compound tag. Normally never seen. 1 TAG_Byte A tag containing 1 byte of data. 2 TAG_Short A tag containing 1 short(Number value) 3 TAG_Int A tag containing 1 integer 4 TAG_Long A tag containing 1 long 5 TAG_Float A tag containing 1 float 6 TAG_Double A tag containing 1 double 7 TAG_Byte_Array A tag containing an array of bytes 8 TAG_String A tag containing a string 9 TAG_List A list of nameless tags of the same type. 10 TAG_Compound A list of named tag. The start of each NBT file. Can contain other compounds. 11 TAG_Int_Array An array of integers Information taken from the MinecraftCoalition page on NBT. Please see the bottom of the page under "read more".

Writing the block class

If it was an item we was making, you can get the tag compound from the ItemStack the item resolves in. I might make another tutorial about that. But because we are working with a block, we need to use something called a TileEntity to save NBT values. A TileEntity is basically a entity connected to a block, used to store stuff for the block. First, we make the constructor. Please note that the class extends BlockContainer.

public BlockVisitor(int id) {

       super(id, 35, Material.circuits);
       // TODO Auto-generated constructor stub

} I won't go through this in detail, because you should allready know this stuff. Next, the method used for detecting right clicks. 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;

} Lets go through the content line for line... if(!world.isRemote) This line checks if it is the server or client calling this. isRemote is true if it is the client, because after Minecraft 1.2.5, single player is run on a local server. Therefore, this is a easy way of detecting server/client. TileEntityVisitor t = (TileEntityVisitor) world.getBlockTileEntity(par2, par3, par4); This line gives us the variable t, by getting a tile entity from the world with the getBlockTileEntity method. par2, 3, and 4 are x, y, and z coordinates. Notice how we cast to a TileEntityVisitor. t.processActivate(par5EntityPlayer, world); There is a method i made in our tileEntity called processActivate, that we use to do all the stuff in registering, and printing. The arguments are the player, and the world. Now we need to add a method to the file that tells Minecraft that we are using a tile entity: public boolean hasTileEntity(int metadata) {

   return true;

} The last method in the block file is the createNewTileEntity() method. It is quite simple, it just returns a new instance of a TileEntityVisitor: public TileEntity createNewTileEntity(World par1World) {

   try
   {
       return new TileEntityVisitor();
   }
   catch (Exception var3)
   {
       throw new RuntimeException(var3);
   }

} We are now done with the block file. Lets move on to the tile entity file.

Making the TileEntity

The TileEntity does not need a constructor. In fact, the first thing we do is to declare the variables containing the visitors: String visitor1="none"; String visitor2="none"; String visitor3="none"; String visitor4="none"; String visitor5="none"; I'm not using an array. Sue me. The next thing we are going to do is to write the method that loads the information from the 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");

} As you can se, we get a NBTTagComponund to use for reading. The rest of the code is quite self-explaining. On a note, remember to run super.readFromNBT(TagCompound); Because a lot of information is actually saved and loaded my the tileentity itself. The next method saves to 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);

} This code is also very self-explanatory. The last method to add is the one called in the block. 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);

} This might require some explanation: if(!visitor1.equals(par5EntityPlayer.getEntityName())) This makes sure you cant register twice in a row in the guest list. visitor5=visitor4; visitor4=visitor3; visitor3=visitor2; visitor2=visitor1; visitor1=par5EntityPlayer.getEntityName(); This part shifts the guest list. world.notifyBlockChange(xCoord, yCoord, zCoord, 2); To be safe. This method tells the world to update neighbour blocks. Please note that i also print the visitors to the chat.

All the code

VisitorBlock.java(Main code file) 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 (Block class) 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);
   }

}

Please note

You have to register the tileEntity with Forge, using: GameRegistry.registerTileEntity(TileEntityVisitor.class, "visitorBlock"); Read more

NBT page at Minecraft Coalition Categories: TutorialsTutorials/Intermediate