提供: Minecraft Modding Wiki
移動先: 案内検索
(ソースコード)
22行目: 22行目:
  
 
@Mod(modid="TileEntitySampleMod", name="TileEntitySampleMod", version="1.0")
 
@Mod(modid="TileEntitySampleMod", name="TileEntitySampleMod", version="1.0")
@NetworkMod(packetHandler = PacketHandler.class)
+
@NetworkMod(channels = "updateTile", packetHandler = PacketHandler.class)
 
public class SampleTileEntityCore {
 
public class SampleTileEntityCore {
  
955行目: 955行目:
  
 
@Override
 
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) {
+
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
 +
{
 +
if (packet.channel.equals("updateTile")) {
 +
ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
  
ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);
+
int x = data.readInt();
 +
int y = data.readInt();
 +
int z = data.readInt();
  
int x = data.readInt();
+
TileEntity tileentity = null;
int y = data.readInt();
 
int z = data.readInt();
 
  
TileEntity tileentity = null;
+
World worldClient = FMLClientHandler.instance().getClient().theWorld;
 +
World worldServer = ((EntityPlayer) player).worldObj;
 +
 
 +
if (worldClient != null && worldServer == null)
 +
{
 +
tileentity = worldClient.getBlockTileEntity(x, y, z);
 +
}
  
World worldClient = FMLClientHandler.instance().getClient().theWorld;
+
if (worldServer != null)
World worldServer = ((EntityPlayer)player).worldObj;
+
{
 +
tileentity = worldServer.getBlockTileEntity(x, y, z);
 +
}
  
if(worldClient != null && worldServer == null){
+
if (tileentity != null)
tileentity = worldClient.getBlockTileEntity(x, y, z);
+
{
 +
if (tileentity instanceof TileEntityBlueFurnace)
 +
{
 +
((TileEntityBlueFurnace) tileentity).readToPacket(data);
 +
}
 +
}
 
}
 
}
if(worldServer != null){
+
}
tileentity = worldServer.getBlockTileEntity(x, y, z);
+
 
 +
public static Packet getPacket(TileEntityBlueFurnace tileentity)
 +
{
 +
ByteArrayOutputStream bos = new ByteArrayOutputStream();
 +
DataOutputStream dos = new DataOutputStream(bos);
 +
 
 +
int x = tileentity.xCoord;
 +
int y = tileentity.yCoord;
 +
int z = tileentity.zCoord;
 +
 
 +
try
 +
{
 +
dos.writeInt(x);
 +
dos.writeInt(y);
 +
dos.writeInt(z);
 +
 
 +
tileentity.writeToPacket(dos);
 
}
 
}
if (tileentity != null) {
+
catch (Exception e)
if(tileentity instanceof TileEntitySample) ((TileEntitySample)tileentity).readToPacket(data);
+
{
 +
e.printStackTrace();
 
}
 
}
 +
 +
Packet250CustomPayload packet = new Packet250CustomPayload();
 +
 +
packet.data = bos.toByteArray();
 +
packet.length = bos.size();
 +
packet.isChunkDataPacket = true;
 +
 +
return packet;
 
}
 
}
  
public static Packet getPacket(TileEntitySample tileentity)
+
public static Packet getPacket(TileEntityRedFurnace tileentity)
 
{
 
{
 
ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
DataOutputStream dos = new DataOutputStream(bos);
 
DataOutputStream dos = new DataOutputStream(bos);
+
 
 
int x = tileentity.xCoord;
 
int x = tileentity.xCoord;
 
int y = tileentity.yCoord;
 
int y = tileentity.yCoord;
 
int z = tileentity.zCoord;
 
int z = tileentity.zCoord;
+
 
 
try
 
try
 
{
 
{
993行目: 1,034行目:
 
dos.writeInt(y);
 
dos.writeInt(y);
 
dos.writeInt(z);
 
dos.writeInt(z);
 +
 
tileentity.writeToPacket(dos);
 
tileentity.writeToPacket(dos);
 
}
 
}
999行目: 1,041行目:
 
e.printStackTrace();
 
e.printStackTrace();
 
}
 
}
+
 
 
Packet250CustomPayload packet = new Packet250CustomPayload();
 
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.data   = bos.toByteArray();
+
 
packet.length = bos.size();
+
packet.channel = "updateTile";
 +
packet.data = bos.toByteArray();
 +
packet.length = bos.size();
 
packet.isChunkDataPacket = true;
 
packet.isChunkDataPacket = true;
+
 
 
return packet;
 
return packet;
 
}
 
}

2013年12月11日 (水) 16:16時点における版

この記事は"Minecraft Forge Universal 9.10.0.xxx~"を前提MODとしています。

TileEntityの追加

かまどとほぼ同じ機能を果たすブロックを作る

ソースコード

  • SampleTileEntityCore.java
package mods.tileentitysample;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.Mod.EventHandler;
import cpw.mods.fml.common.Mod.Instance;
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.network.NetworkRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.LanguageRegistry;

@Mod(modid="TileEntitySampleMod", name="TileEntitySampleMod", version="1.0")
@NetworkMod(channels = "updateTile", packetHandler = PacketHandler.class)
public class SampleTileEntityCore {

	public static Block blockSample;
	public static int blockSampleID = 4087;

	public static int guiSampleID = 1000;
 
	//SampleTileEntityCoreクラスのインスタンス
	@Instance("TileEntitySampleMod")
	public static SampleTileEntityCore instance;

	@EventHandler
	public void init(FMLInitializationEvent event)
	{
		//表示名の登録
		LanguageRegistry.addName(blockSample, "Sample Block");
		LanguageRegistry.instance().addNameForObject(blockSample, "ja_JP", "サンプル ブロック");

		//TileEntityの登録
		GameRegistry.registerTileEntity(TileEntitySample.class, "TileEntitySample");

		//GUIの登録
		NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler());
	}
 
	@EventHandler
	public void preInit(FMLPreInitializationEvent event)
	{
		//ブロックの登録
		blockSample = new BlockContainerSample(blockSampleID, Material.rock);
		GameRegistry.registerBlock(blockSample, "blockSample");
	}

}
  • BlockContainerSample.java
package mods.tileentitysample;

import java.util.Random;

import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

public class BlockContainerSample extends BlockContainer {

	protected Random rand = new Random();

	protected BlockContainerSample(int par1, Material par2Material) {
		super(par1, par2Material);
	}

	//右クリックされた時の処理
	@Override
	public boolean onBlockActivated(World par1World, int par2, int par3, int par4, EntityPlayer par5EntityPlayer, int par6, float par7, float par8, float par9){
		if (par1World.isRemote)
		{
			return true;
		}
		else
		{
			// GUIを開く
			par5EntityPlayer.openGui(SampleTileEntityCore.instance, SampleTileEntityCore.instance.guiSampleID, par1World, par2, par3, par4);
			return true;
		}
	}

	//ブロックが壊れた時の処理
	//周辺に中に入っていたアイテムをまき散らす
	@Override
	public void breakBlock(World par1World, int par2, int par3, int par4, int par5, int par6)
	{
		TileEntitySample tileentity = (TileEntitySample) par1World.getBlockTileEntity(par2, par3, par4);

		if (tileentity != null)
		{
			for (int j1 = 0; j1 < tileentity.inventory.getSizeInventory(); ++j1)
			{
				ItemStack itemstack = tileentity.inventory.getStackInSlot(j1);

				if (itemstack != null)
				{
					float f = this.rand.nextFloat() * 0.8F + 0.1F;
					float f1 = this.rand.nextFloat() * 0.8F + 0.1F;
					float f2 = this.rand.nextFloat() * 0.8F + 0.1F;

					while (itemstack.stackSize > 0)
					{
						int k1 = this.rand.nextInt(21) + 10;

						if (k1 > itemstack.stackSize)
						{
							k1 = itemstack.stackSize;
						}

						itemstack.stackSize -= k1;
						EntityItem entityitem = new EntityItem(par1World, (double)((float)par2 + f), (double)((float)par3 + f1), (double)((float)par4 + f2), new ItemStack(itemstack.itemID, k1, itemstack.getItemDamage()));

						if (itemstack.hasTagCompound())
						{
							entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy());
						}

						float f3 = 0.05F;
						entityitem.motionX = (double)((float)this.rand.nextGaussian() * f3);
						entityitem.motionY = (double)((float)this.rand.nextGaussian() * f3 + 0.2F);
						entityitem.motionZ = (double)((float)this.rand.nextGaussian() * f3);
						par1World.spawnEntityInWorld(entityitem);
					}
				}
			}

			par1World.func_96440_m(par2, par3, par4, par5);
		}

		super.breakBlock(par1World, par2, par3, par4, par5, par6);
	}

	@Override
	public TileEntity createNewTileEntity(World world) {
		// TileEntityの生成
		return new TileEntitySample();
	}

}
  • TileEntitySample.java
package mods.tileentitysample;

import java.io.DataOutputStream;
import java.io.IOException;

import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemHoe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemSword;
import net.minecraft.item.ItemTool;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.network.packet.Packet;
import net.minecraft.tileentity.TileEntity;

import com.google.common.io.ByteArrayDataInput;

import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class TileEntitySample extends TileEntity
{

	//燃焼時間
	public int burnTime;

	public int currentItemBurnTime;

	//調理時間
	public int cookTime;

	public InventorySample inventory;

	public TileEntitySample() {
		this.inventory = new InventorySample(this);
	}

	@Override
	public void readFromNBT(NBTTagCompound par1NBTTagCompound)
	{
		super.readFromNBT(par1NBTTagCompound);

		//アイテムの読み込み
		NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items");
		this.inventory.sampleItemStacks = new ItemStack[this.inventory.getSizeInventory()];

		for (int i = 0; i < nbttaglist.tagCount(); ++i)
		{
			NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i);
			byte b0 = nbttagcompound1.getByte("Slot");

			if (b0 >= 0 && b0 < this.inventory.sampleItemStacks.length)
			{
				this.inventory.sampleItemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1);
			}
		}

		//燃焼時間や調理時間などの読み込み
		this.burnTime = par1NBTTagCompound.getShort("BurnTime");
		this.cookTime = par1NBTTagCompound.getShort("CookTime");
		this.currentItemBurnTime = getItemBurnTime(this.inventory.sampleItemStacks[1]);

	}

	@Override
	public void writeToNBT(NBTTagCompound par1NBTTagCompound)
	{
		super.writeToNBT(par1NBTTagCompound);

		//燃焼時間や調理時間などの書き込み
		par1NBTTagCompound.setShort("BurnTime", (short)this.burnTime);
		par1NBTTagCompound.setShort("CookTime", (short)this.cookTime);

		//アイテムの書き込み
		NBTTagList nbttaglist = new NBTTagList();

		for (int i = 0; i < this.inventory.sampleItemStacks.length; ++i)
		{
			if (this.inventory.sampleItemStacks[i] != null)
			{
				NBTTagCompound nbttagcompound1 = new NBTTagCompound();
				nbttagcompound1.setByte("Slot", (byte)i);
				this.inventory.sampleItemStacks[i].writeToNBT(nbttagcompound1);
				nbttaglist.appendTag(nbttagcompound1);
			}
		}

		par1NBTTagCompound.setTag("Items", nbttaglist);

	}

	public void readToPacket(ByteArrayDataInput data) {
		//アイテムの読み込み
		for (int i = 0; i < this.inventory.getSizeInventory(); i++) {
			int id = data.readInt();
			int stacksize = data.readByte();
			int metadata = data.readInt();

			if (id != 0 && stacksize != 0) {
				this.inventory.setInventorySlotContents(i, new ItemStack(id, stacksize, metadata));
			} else {
				this.inventory.setInventorySlotContents(i, null);
			}
		}
	}

	public void writeToPacket(DataOutputStream dos) {
		try {
			//アイテムの書き込み
			for (int i = 0; i < this.inventory.getSizeInventory(); i++) {
				int id = this.inventory.sampleItemStacks[i] != null ? this.inventory.sampleItemStacks[i].itemID : 0;
				int stacksize = this.inventory.sampleItemStacks[i] != null ? this.inventory.sampleItemStacks[i].stackSize : 0;
				int metadata = this.inventory.sampleItemStacks[i] != null ? this.inventory.sampleItemStacks[i].getItemDamage() : 0;

				dos.writeInt(id);
				dos.writeByte(stacksize);
				dos.writeInt(metadata);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public Packet getDescriptionPacket()
	{
		//パケットの取得
		return PacketHandler.getPacket(this);
	}

	//かまどの処理
	@SideOnly(Side.CLIENT)
	public int getCookProgressScaled(int par1)
	{
		return this.cookTime * par1 / 200;
	}

	//かまどの処理
	@SideOnly(Side.CLIENT)
	public int getBurnTimeRemainingScaled(int par1)
	{
		if (this.currentItemBurnTime == 0)
		{
			this.currentItemBurnTime = 200;
		}

		return this.burnTime * par1 / this.currentItemBurnTime;
	}

	//かまどの処理
	public boolean isBurning()
	{
		return this.burnTime > 0;
	}

	//更新時に呼び出される
	//かまどの処理
	public void updateEntity()
	{
		boolean flag = this.burnTime > 0;
		boolean flag1 = false;

		if (this.burnTime > 0)
		{
			--this.burnTime;
		}

		if (!this.worldObj.isRemote)
		{
			if (this.burnTime == 0 && this.canSmelt())
			{
				this.currentItemBurnTime = this.burnTime = getItemBurnTime(this.inventory.sampleItemStacks[1]);

				if (this.burnTime > 0)
				{
					flag1 = true;

					if (this.inventory.sampleItemStacks[1] != null)
					{
						--this.inventory.sampleItemStacks[1].stackSize;

						if (this.inventory.sampleItemStacks[1].stackSize == 0)
						{
							this.inventory.sampleItemStacks[1] = this.inventory.sampleItemStacks[1].getItem().getContainerItemStack(this.inventory.sampleItemStacks[1]);
						}
					}
				}
			}

			if (this.isBurning() && this.canSmelt())
			{
				++this.cookTime;

				if (this.cookTime == 200)
				{
					this.cookTime = 0;
					this.smeltItem();
					flag1 = true;
				}
			}
			else
			{
				this.cookTime = 0;
			}

			if (flag != this.burnTime > 0)
			{
				flag1 = true;
			}
		}

		if (flag1)
		{
			this.onInventoryChanged();
		}
	}

	//かまどの処理
	private boolean canSmelt()
	{
		if (this.inventory.sampleItemStacks[0] == null)
		{
			return false;
		}
		else
		{
			ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.inventory.sampleItemStacks[0]);
			if (itemstack == null) return false;
			if (this.inventory.sampleItemStacks[2] == null) return true;
			if (!this.inventory.sampleItemStacks[2].isItemEqual(itemstack)) return false;
			int result = this.inventory.sampleItemStacks[2].stackSize + itemstack.stackSize;
			return (result <= this.inventory.getInventoryStackLimit() && result <= itemstack.getMaxStackSize());
		}
	}

	//かまどの処理
	public void smeltItem()
	{
		if (this.canSmelt())
		{
			ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.inventory.sampleItemStacks[0]);

			if (this.inventory.sampleItemStacks[2] == null)
			{
				this.inventory.sampleItemStacks[2] = itemstack.copy();
			}
			else if (this.inventory.sampleItemStacks[2].isItemEqual(itemstack))
			{
				this.inventory.sampleItemStacks[2].stackSize += itemstack.stackSize;
			}

			--this.inventory.sampleItemStacks[0].stackSize;

			if (this.inventory.sampleItemStacks[0].stackSize <= 0)
			{
				this.inventory.sampleItemStacks[0] = null;
			}
		}
	}

	//かまどの処理
	public static int getItemBurnTime(ItemStack par0ItemStack)
	{
		if (par0ItemStack == null)
		{
			return 0;
		}
		else
		{
			int i = par0ItemStack.getItem().itemID;
			Item item = par0ItemStack.getItem();

			if (par0ItemStack.getItem() instanceof ItemBlock && Block.blocksList[i] != null)
			{
				Block block = Block.blocksList[i];

				if (block == Block.woodSingleSlab)
				{
					return 150;
				}

				if (block.blockMaterial == Material.wood)
				{
					return 300;
				}

				if (block == Block.field_111034_cE)
				{
					return 16000;
				}
			}

			if (item instanceof ItemTool && ((ItemTool) item).getToolMaterialName().equals("WOOD")) return 200;
			if (item instanceof ItemSword && ((ItemSword) item).getToolMaterialName().equals("WOOD")) return 200;
			if (item instanceof ItemHoe && ((ItemHoe) item).getMaterialName().equals("WOOD")) return 200;
			if (i == Item.stick.itemID) return 100;
			if (i == Item.coal.itemID) return 1600;
			if (i == Item.bucketLava.itemID) return 20000;
			if (i == Block.sapling.blockID) return 100;
			if (i == Item.blazeRod.itemID) return 2400;
			return GameRegistry.getFuelValue(par0ItemStack);
		}
	}

	//かまどの処理
	public static boolean isItemFuel(ItemStack par0ItemStack)
	{
		return getItemBurnTime(par0ItemStack) > 0;
	}

}
  • InventorySample.java
package mods.tileentitysample;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

public class InventorySample implements ISidedInventory {

	private static final int[] slots_top = new int[] {0};
	private static final int[] slots_bottom = new int[] {2, 1};
	private static final int[] slots_sides = new int[] {1};

	public ItemStack[] sampleItemStacks = new ItemStack[3];

	private TileEntitySample tileentity;

	public InventorySample(TileEntitySample tileentity) {
		this.tileentity = tileentity;
	}

	// スロット数
	@Override
	public int getSizeInventory() {
		return this.sampleItemStacks.length;
	}

	// インベントリ内の任意のスロットにあるアイテムを取得
	@Override
	public ItemStack getStackInSlot(int par1) {
		return this.sampleItemStacks[par1];
	}

	@Override
	public ItemStack decrStackSize(int par1, int par2) {
		if (this.sampleItemStacks[par1] != null)
		{
			ItemStack itemstack;

			if (this.sampleItemStacks[par1].stackSize <= par2)
			{
				itemstack = this.sampleItemStacks[par1];
				this.sampleItemStacks[par1] = null;
				return itemstack;
			}
			else
			{
				itemstack = this.sampleItemStacks[par1].splitStack(par2);

				if (this.sampleItemStacks[par1].stackSize == 0)
				{
					this.sampleItemStacks[par1] = null;
				}

				return itemstack;
			}
		}
		else
		{
			return null;
		}
	}

	@Override
	public ItemStack getStackInSlotOnClosing(int par1) {
		if (this.sampleItemStacks[par1] != null)
		{
			ItemStack itemstack = this.sampleItemStacks[par1];
			this.sampleItemStacks[par1] = null;
			return itemstack;
		}
		else
		{
			return null;
		}
	}

	// インベントリ内のスロットにアイテムを入れる
	@Override
	public void setInventorySlotContents(int par1, ItemStack par2ItemStack) {
		this.sampleItemStacks[par1] = par2ItemStack;

		if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit())
		{
			par2ItemStack.stackSize = this.getInventoryStackLimit();
		}
	}

	// インベントリの名前
	@Override
	public String getInvName() {
		return "Sample";
	}

	// 多言語対応かどうか
	@Override
	public boolean isInvNameLocalized() {
		return false;
	}

	// インベントリ内のスタック限界値
	@Override
	public int getInventoryStackLimit() {
		return 64;
	}

	@Override
	public void onInventoryChanged() {
		this.tileentity.onInventoryChanged();
	}

	// par1EntityPlayerがTileEntityを使えるかどうか
	@Override
	public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) {
		return this.tileentity.worldObj.getBlockTileEntity(this.tileentity.xCoord, this.tileentity.yCoord, this.tileentity.zCoord) != this.tileentity ? false : par1EntityPlayer.getDistanceSq((double) this.tileentity.xCoord + 0.5D, (double) this.tileentity.yCoord + 0.5D, (double) this.tileentity.zCoord + 0.5D) <= 64.0D;
	}

	@Override
	public void openChest() {}

	@Override
	public void closeChest() {}

	@Override
	public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) {
		return par1 == 2 ? false : (par1 == 1 ? this.tileentity.isItemFuel(par2ItemStack) : true);
	}

	//ホッパーにアイテムの受け渡しをする際の優先度
	@Override
	public int[] getAccessibleSlotsFromSide(int par1) {
		return par1 == 0 ? slots_bottom : (par1 == 1 ? slots_top : slots_sides);
	}

	//ホッパーからアイテムを入れられるかどうか
	@Override
	public boolean canInsertItem(int par1, ItemStack par2ItemStack, int par3) {
		return this.isItemValidForSlot(par1, par2ItemStack);
	}

	//隣接するホッパーにアイテムを送れるかどうか
	@Override
	public boolean canExtractItem(int par1, ItemStack par2ItemStack, int par3) {
		return par3 != 0 || par1 != 1 || par2ItemStack.itemID == Item.bucketEmpty.itemID;
	}

}
  • ContainerSample.java
package mods.tileentitysample;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.inventory.SlotFurnace;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.tileentity.TileEntityFurnace;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;

public class ContainerSample extends Container {

	private TileEntitySample tileentity;

	private InventorySample inventory;

	private int lastCookTime;
	private int lastBurnTime;
	private int lastItemBurnTime;

	public ContainerSample(EntityPlayer player, TileEntitySample par2TileEntity) {
		this.tileentity = par2TileEntity;
		this.inventory = par2TileEntity.inventory;

		// InventorySampleで追加するインベントリ
		this.addSlotToContainer(new Slot(this.inventory, 0, 56, 17));
		this.addSlotToContainer(new Slot(this.inventory, 1, 56, 53));
		this.addSlotToContainer(new SlotFurnace(player, this.inventory, 2, 116, 35));
		int i;

		// 1 ~ 3段目のインベントリ
		for (i = 0; i < 3; ++i)
		{
			for (int j = 0; j < 9; ++j)
			{
				this.addSlotToContainer(new Slot(player.inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
			}
		}

		// 4段目のインベントリ
		for (i = 0; i < 9; ++i)
		{
			this.addSlotToContainer(new Slot(player.inventory, i, 8 + i * 18, 142));
		}
	}

	public void addCraftingToCrafters(ICrafting par1ICrafting)
	{
		super.addCraftingToCrafters(par1ICrafting);
		par1ICrafting.sendProgressBarUpdate(this, 0, this.tileentity.cookTime);
		par1ICrafting.sendProgressBarUpdate(this, 1, this.tileentity.burnTime);
		par1ICrafting.sendProgressBarUpdate(this, 2, this.tileentity.currentItemBurnTime);
	}

	// 更新を送る
	public void detectAndSendChanges()
	{
		super.detectAndSendChanges();

		for (int i = 0; i < this.crafters.size(); ++i)
		{
			ICrafting icrafting = (ICrafting)this.crafters.get(i);

			if (this.lastCookTime != this.tileentity.cookTime)
			{
				icrafting.sendProgressBarUpdate(this, 0, this.tileentity.cookTime);
			}

			if (this.lastBurnTime != this.tileentity.burnTime)
			{
				icrafting.sendProgressBarUpdate(this, 1, this.tileentity.burnTime);
			}

			if (this.lastItemBurnTime != this.tileentity.currentItemBurnTime)
			{
				icrafting.sendProgressBarUpdate(this, 2, this.tileentity.currentItemBurnTime);
			}
		}

		this.lastCookTime = this.tileentity.cookTime;
		this.lastBurnTime = this.tileentity.burnTime;
		this.lastItemBurnTime = this.tileentity.currentItemBurnTime;
	}

	// 更新する
	@SideOnly(Side.CLIENT)
	public void updateProgressBar(int par1, int par2)
	{
		if (par1 == 0)
		{
			this.tileentity.cookTime = par2;
		}

		if (par1 == 1)
		{
			this.tileentity.burnTime = par2;
		}

		if (par1 == 2)
		{
			this.tileentity.currentItemBurnTime = par2;
		}
	}

	// InventorySample内のisUseableByPlayerメソッドを参照
	@Override
	public boolean canInteractWith(EntityPlayer par1EntityPlayer) {
		return this.inventory.isUseableByPlayer(par1EntityPlayer);
	}

	// Shiftクリック
	public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2)
	{
		ItemStack itemstack = null;
		Slot slot = (Slot)this.inventorySlots.get(par2);

		if (slot != null && slot.getHasStack())
		{
			ItemStack itemstack1 = slot.getStack();
			itemstack = itemstack1.copy();

			//スロット番号が2の時
			if (par2 == 2)
			{
				//アイテムの移動(スロット3~39へ)
				if (!this.mergeItemStack(itemstack1, 3, 39, true))
				{
					return null;
				}

				slot.onSlotChange(itemstack1, itemstack);
			}
			//スロット番号が0、1でない時
			else if (par2 != 1 && par2 != 0)
			{
				if (FurnaceRecipes.smelting().getSmeltingResult(itemstack1) != null)
				{
					//アイテムの移動(スロット0~1へ)
					if (!this.mergeItemStack(itemstack1, 0, 1, false))
					{
						return null;
					}
				}
				else if (TileEntityFurnace.isItemFuel(itemstack1))
				{
					//アイテムの移動(スロット1~2へ)
					if (!this.mergeItemStack(itemstack1, 1, 2, false))
					{
						return null;
					}
				}
				else if (par2 >= 3 && par2 < 30)
				{
					//アイテムの移動(スロット30~39へ)
					if (!this.mergeItemStack(itemstack1, 30, 39, false))
					{
						return null;
					}
				}
				else if (par2 >= 30 && par2 < 39 && !this.mergeItemStack(itemstack1, 3, 30, false))
				{
					return null;
				}
			}
			//アイテムの移動(スロット3~39へ)
			else if (!this.mergeItemStack(itemstack1, 3, 39, false))
			{
				return null;
			}

			if (itemstack1.stackSize == 0)
			{
				slot.putStack((ItemStack)null);
			}
			else
			{
				slot.onSlotChanged();
			}

			if (itemstack1.stackSize == itemstack.stackSize)
			{
				return null;
			}

			slot.onPickupFromSlot(par1EntityPlayer, itemstack1);
		}

		return itemstack;
	}

}
  • GuiSample.java
package mods.tileentitysample;

import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation;

import org.lwjgl.opengl.GL11;

public class GuiSample extends GuiContainer {

	private TileEntitySample tileentity;
	private InventorySample inventory;

	public GuiSample(EntityPlayer player, TileEntitySample par2TileEntity) {
		super(new ContainerSample(player, par2TileEntity));
		this.tileentity = par2TileEntity;
		this.inventory = par2TileEntity.inventory;
	}

	@Override
	protected void drawGuiContainerForegroundLayer(int par1, int par2)
	{
		//インベントリ名の描画
		String s = this.inventory.isInvNameLocalized() ? this.inventory.getInvName() : I18n.func_135053_a(this.inventory.getInvName());
		this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752);
		this.fontRenderer.drawString(I18n.func_135053_a("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
	}

	@Override
	protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3)
	{
		GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);

		//テクスチャの指定
		//ResourceLocationの第一引数を付け足してドメインを指定することもできる
		//例:new ResourceLocation("sample", "textures/gui/container/furnace.png")
		this.mc.func_110434_K().func_110577_a(new ResourceLocation("textures/gui/container/furnace.png"));

		//かまど描画処理
		int k = (this.width - this.xSize) / 2;
		int l = (this.height - this.ySize) / 2;
		this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
		int i1;

		if (this.tileentity.isBurning())
		{
			i1 = this.tileentity.getBurnTimeRemainingScaled(12);
			this.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 2);
		}

		i1 = this.tileentity.getCookProgressScaled(24);
		this.drawTexturedModalRect(k + 79, l + 34, 176, 14, i1 + 1, 16);
	}

}
  • GuiHandler.java
package mods.tileentitysample;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import cpw.mods.fml.common.network.IGuiHandler;

public class GuiHandler implements IGuiHandler {

	@Override
	public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
		if (!world.blockExists(x, y, z))
			return null;

		TileEntity tileentity = world.getBlockTileEntity(x, y, z);
		if (tileentity instanceof TileEntitySample) {
			return new ContainerSample(player, (TileEntitySample) tileentity);
		}
		return null;
	}

	@Override
	public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
		if (!world.blockExists(x, y, z))
			return null;

		TileEntity tileentity = world.getBlockTileEntity(x, y, z);
		if (tileentity instanceof TileEntitySample) {
			return new GuiSample(player, (TileEntitySample) tileentity);
		}
		return null;
	}

}
  • PacketHandler.java
package mods.tileentitysample;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetworkManager;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.Packet250CustomPayload;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;

import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.network.IPacketHandler;
import cpw.mods.fml.common.network.Player;

public class PacketHandler implements IPacketHandler {

	@Override
	public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
	{
		if (packet.channel.equals("updateTile")) {
			ByteArrayDataInput data = ByteStreams.newDataInput(packet.data);

			int x = data.readInt();
			int y = data.readInt();
			int z = data.readInt();

			TileEntity tileentity = null;

			World worldClient = FMLClientHandler.instance().getClient().theWorld;
			World worldServer = ((EntityPlayer) player).worldObj;

			if (worldClient != null && worldServer == null)
			{
				tileentity = worldClient.getBlockTileEntity(x, y, z);
			}

			if (worldServer != null)
			{
				tileentity = worldServer.getBlockTileEntity(x, y, z);
			}

			if (tileentity != null)
			{
				if (tileentity instanceof TileEntityBlueFurnace)
				{
					((TileEntityBlueFurnace) tileentity).readToPacket(data);
				}
			}
		}
	}

	public static Packet getPacket(TileEntityBlueFurnace tileentity)
	{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(bos);

		int x = tileentity.xCoord;
		int y = tileentity.yCoord;
		int z = tileentity.zCoord;

		try
		{
			dos.writeInt(x);
			dos.writeInt(y);
			dos.writeInt(z);

			tileentity.writeToPacket(dos);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		Packet250CustomPayload packet = new Packet250CustomPayload();

		packet.data = bos.toByteArray();
		packet.length = bos.size();
		packet.isChunkDataPacket = true;

		return packet;
	}

	public static Packet getPacket(TileEntityRedFurnace tileentity)
	{
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		DataOutputStream dos = new DataOutputStream(bos);

		int x = tileentity.xCoord;
		int y = tileentity.yCoord;
		int z = tileentity.zCoord;

		try
		{
			dos.writeInt(x);
			dos.writeInt(y);
			dos.writeInt(z);

			tileentity.writeToPacket(dos);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}

		Packet250CustomPayload packet = new Packet250CustomPayload();

		packet.channel = "updateTile";
		packet.data = bos.toByteArray();
		packet.length = bos.size();
		packet.isChunkDataPacket = true;

		return packet;
	}

}

解説

SampleTileEntityCore.java

ブロックの追加方法の解説は1.6のブロック追加

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

TileEntityの登録を行います。 第一引数がTileEntityを継承したクラス、第二引数は他と被らない文字列。

NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler());

Guiを扱うGuiHandlerの登録を登録します。

TileEntitySample.java

@Override
public void readFromNBT(NBTTagCompound par1NBTTagCompound)
{
	super.readFromNBT(par1NBTTagCompound);

	~ 中略 ~

}

@Override
public void writeToNBT(NBTTagCompound par1NBTTagCompound)
{
	super.writeToNBT(par1NBTTagCompound);

	~ 中略 ~

}

上記2つのメソッドを使ってTileEntityの情報をNBTに保存します。

public void readToPacket(ByteArrayDataInput data) {
	~ 中略 ~
}

public void writeToPacket(DataOutputStream dos) {
	~ 中略 ~
}

@Override
public Packet getDescriptionPacket()
{
	//パケットの取得
	return PacketHandler.getPacket(this);
}

NBTに保存した情報をパケットで飛ばすことができる。