提供: Minecraft Modding Wiki
細 |
|||
(3人の利用者による、間の6版が非表示) | |||
1行目: | 1行目: | ||
− | {{前提MOD|reqmod="Minecraft Forge Universal 9. | + | {{前提MOD|reqmod="Minecraft Forge Universal 9.11.1.xxx~"}} |
− | + | {{チュートリアル難易度| difficulty=2 |clear=none}} | |
+ | {{チュートリアルカテゴリー| difficulty=2 | type=Block }} | ||
==TileEntityの追加== | ==TileEntityの追加== | ||
<p>かまどとほぼ同じ機能を果たすブロックを作る</p> | <p>かまどとほぼ同じ機能を果たすブロックを作る</p> | ||
7行目: | 8行目: | ||
*SampleTileEntityCore.java | *SampleTileEntityCore.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
import net.minecraft.block.Block; | import net.minecraft.block.Block; | ||
import net.minecraft.block.material.Material; | import net.minecraft.block.material.Material; | ||
20行目: | 21行目: | ||
import cpw.mods.fml.common.registry.GameRegistry; | import cpw.mods.fml.common.registry.GameRegistry; | ||
import cpw.mods.fml.common.registry.LanguageRegistry; | import cpw.mods.fml.common.registry.LanguageRegistry; | ||
− | + | ||
@Mod(modid="TileEntitySampleMod", name="TileEntitySampleMod", version="1.0") | @Mod(modid="TileEntitySampleMod", name="TileEntitySampleMod", version="1.0") | ||
− | @NetworkMod( | + | @NetworkMod(clientSideRequired = true, serverSideRequired = false) |
public class SampleTileEntityCore { | public class SampleTileEntityCore { | ||
− | + | ||
public static Block blockSample; | public static Block blockSample; | ||
public static int blockSampleID = 4087; | public static int blockSampleID = 4087; | ||
− | + | ||
public static int guiSampleID = 1000; | public static int guiSampleID = 1000; | ||
33行目: | 34行目: | ||
@Instance("TileEntitySampleMod") | @Instance("TileEntitySampleMod") | ||
public static SampleTileEntityCore instance; | public static SampleTileEntityCore instance; | ||
− | + | ||
@EventHandler | @EventHandler | ||
public void init(FMLInitializationEvent event) | public void init(FMLInitializationEvent event) | ||
40行目: | 41行目: | ||
LanguageRegistry.addName(blockSample, "Sample Block"); | LanguageRegistry.addName(blockSample, "Sample Block"); | ||
LanguageRegistry.instance().addNameForObject(blockSample, "ja_JP", "サンプル ブロック"); | LanguageRegistry.instance().addNameForObject(blockSample, "ja_JP", "サンプル ブロック"); | ||
− | + | ||
//TileEntityの登録 | //TileEntityの登録 | ||
GameRegistry.registerTileEntity(TileEntitySample.class, "TileEntitySample"); | GameRegistry.registerTileEntity(TileEntitySample.class, "TileEntitySample"); | ||
− | + | ||
//GUIの登録 | //GUIの登録 | ||
NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler()); | NetworkRegistry.instance().registerGuiHandler(this, new GuiHandler()); | ||
55行目: | 56行目: | ||
GameRegistry.registerBlock(blockSample, "blockSample"); | GameRegistry.registerBlock(blockSample, "blockSample"); | ||
} | } | ||
− | + | ||
} | } | ||
62行目: | 63行目: | ||
*BlockContainerSample.java | *BlockContainerSample.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
− | |||
− | |||
import net.minecraft.block.BlockContainer; | import net.minecraft.block.BlockContainer; | ||
import net.minecraft.block.material.Material; | import net.minecraft.block.material.Material; | ||
74行目: | 73行目: | ||
import net.minecraft.tileentity.TileEntity; | import net.minecraft.tileentity.TileEntity; | ||
import net.minecraft.world.World; | import net.minecraft.world.World; | ||
− | + | ||
public class BlockContainerSample extends BlockContainer { | public class BlockContainerSample extends BlockContainer { | ||
− | + | ||
− | |||
− | |||
protected BlockContainerSample(int par1, Material par2Material) { | protected BlockContainerSample(int par1, Material par2Material) { | ||
super(par1, par2Material); | super(par1, par2Material); | ||
} | } | ||
− | + | ||
//右クリックされた時の処理 | //右クリックされた時の処理 | ||
@Override | @Override | ||
97行目: | 94行目: | ||
} | } | ||
} | } | ||
− | + | ||
//ブロックが壊れた時の処理 | //ブロックが壊れた時の処理 | ||
//周辺に中に入っていたアイテムをまき散らす | //周辺に中に入っていたアイテムをまき散らす | ||
104行目: | 101行目: | ||
{ | { | ||
TileEntitySample tileentity = (TileEntitySample) par1World.getBlockTileEntity(par2, par3, par4); | TileEntitySample tileentity = (TileEntitySample) par1World.getBlockTileEntity(par2, par3, par4); | ||
− | + | ||
if (tileentity != null) | if (tileentity != null) | ||
{ | { | ||
− | for (int j1 = 0; j1 < tileentity | + | for (int j1 = 0; j1 < tileentity.getSizeInventory(); ++j1) |
{ | { | ||
− | ItemStack itemstack = tileentity | + | ItemStack itemstack = tileentity.getStackInSlot(j1); |
− | + | ||
if (itemstack != null) | if (itemstack != null) | ||
{ | { | ||
− | float f = | + | float f = par1World.rand.nextFloat() * 0.8F + 0.1F; |
− | float f1 = | + | float f1 = par1World.rand.nextFloat() * 0.8F + 0.1F; |
− | float f2 = | + | float f2 = par1World.rand.nextFloat() * 0.8F + 0.1F; |
− | + | ||
while (itemstack.stackSize > 0) | while (itemstack.stackSize > 0) | ||
{ | { | ||
− | int k1 = | + | int k1 = par1World.rand.nextInt(21) + 10; |
− | + | ||
if (k1 > itemstack.stackSize) | if (k1 > itemstack.stackSize) | ||
{ | { | ||
k1 = itemstack.stackSize; | k1 = itemstack.stackSize; | ||
} | } | ||
− | + | ||
itemstack.stackSize -= k1; | 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())); | 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()) | if (itemstack.hasTagCompound()) | ||
{ | { | ||
entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); | entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); | ||
} | } | ||
− | + | ||
float f3 = 0.05F; | float f3 = 0.05F; | ||
− | entityitem.motionX = (double)((float) | + | entityitem.motionX = (double)((float)par1World.rand.nextGaussian() * f3); |
− | entityitem.motionY = (double)((float) | + | entityitem.motionY = (double)((float)par1World.rand.nextGaussian() * f3 + 0.2F); |
− | entityitem.motionZ = (double)((float) | + | entityitem.motionZ = (double)((float)par1World.rand.nextGaussian() * f3); |
par1World.spawnEntityInWorld(entityitem); | par1World.spawnEntityInWorld(entityitem); | ||
} | } | ||
} | } | ||
} | } | ||
− | + | ||
par1World.func_96440_m(par2, par3, par4, par5); | par1World.func_96440_m(par2, par3, par4, par5); | ||
} | } | ||
− | + | ||
super.breakBlock(par1World, par2, par3, par4, par5, par6); | super.breakBlock(par1World, par2, par3, par4, par5, par6); | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public TileEntity createNewTileEntity(World world) { | public TileEntity createNewTileEntity(World world) { | ||
154行目: | 151行目: | ||
return new TileEntitySample(); | return new TileEntitySample(); | ||
} | } | ||
− | + | ||
} | } | ||
161行目: | 158行目: | ||
*TileEntitySample.java | *TileEntitySample.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
− | |||
− | |||
− | |||
import net.minecraft.block.Block; | import net.minecraft.block.Block; | ||
import net.minecraft.block.material.Material; | import net.minecraft.block.material.Material; | ||
+ | import net.minecraft.entity.player.EntityPlayer; | ||
+ | import net.minecraft.inventory.ISidedInventory; | ||
import net.minecraft.item.Item; | import net.minecraft.item.Item; | ||
import net.minecraft.item.ItemBlock; | import net.minecraft.item.ItemBlock; | ||
177行目: | 173行目: | ||
import net.minecraft.nbt.NBTTagCompound; | import net.minecraft.nbt.NBTTagCompound; | ||
import net.minecraft.nbt.NBTTagList; | import net.minecraft.nbt.NBTTagList; | ||
+ | import net.minecraft.network.INetworkManager; | ||
import net.minecraft.network.packet.Packet; | import net.minecraft.network.packet.Packet; | ||
+ | import net.minecraft.network.packet.Packet132TileEntityData; | ||
import net.minecraft.tileentity.TileEntity; | import net.minecraft.tileentity.TileEntity; | ||
− | |||
− | |||
− | |||
import cpw.mods.fml.common.registry.GameRegistry; | import cpw.mods.fml.common.registry.GameRegistry; | ||
import cpw.mods.fml.relauncher.Side; | import cpw.mods.fml.relauncher.Side; | ||
import cpw.mods.fml.relauncher.SideOnly; | import cpw.mods.fml.relauncher.SideOnly; | ||
− | + | ||
− | public class TileEntitySample extends TileEntity | + | public class TileEntitySample extends TileEntity implements ISidedInventory |
{ | { | ||
− | + | ||
//燃焼時間 | //燃焼時間 | ||
public int burnTime; | public int burnTime; | ||
− | + | ||
public int currentItemBurnTime; | public int currentItemBurnTime; | ||
− | + | ||
//調理時間 | //調理時間 | ||
public int cookTime; | public int cookTime; | ||
− | + | ||
− | + | 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]; | |
− | + | ||
@Override | @Override | ||
public void readFromNBT(NBTTagCompound par1NBTTagCompound) | public void readFromNBT(NBTTagCompound par1NBTTagCompound) | ||
{ | { | ||
super.readFromNBT(par1NBTTagCompound); | super.readFromNBT(par1NBTTagCompound); | ||
− | + | ||
//アイテムの読み込み | //アイテムの読み込み | ||
NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); | NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); | ||
− | this | + | this.sampleItemStacks = new ItemStack[this.getSizeInventory()]; |
− | + | ||
for (int i = 0; i < nbttaglist.tagCount(); ++i) | for (int i = 0; i < nbttaglist.tagCount(); ++i) | ||
{ | { | ||
NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); | NBTTagCompound nbttagcompound1 = (NBTTagCompound)nbttaglist.tagAt(i); | ||
byte b0 = nbttagcompound1.getByte("Slot"); | byte b0 = nbttagcompound1.getByte("Slot"); | ||
− | + | ||
− | if (b0 >= 0 && b0 < this | + | if (b0 >= 0 && b0 < this.sampleItemStacks.length) |
{ | { | ||
− | this | + | this.sampleItemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); |
} | } | ||
} | } | ||
− | + | ||
//燃焼時間や調理時間などの読み込み | //燃焼時間や調理時間などの読み込み | ||
this.burnTime = par1NBTTagCompound.getShort("BurnTime"); | this.burnTime = par1NBTTagCompound.getShort("BurnTime"); | ||
this.cookTime = par1NBTTagCompound.getShort("CookTime"); | this.cookTime = par1NBTTagCompound.getShort("CookTime"); | ||
− | this.currentItemBurnTime = getItemBurnTime(this | + | this.currentItemBurnTime = getItemBurnTime(this.sampleItemStacks[1]); |
− | + | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public void writeToNBT(NBTTagCompound par1NBTTagCompound) | public void writeToNBT(NBTTagCompound par1NBTTagCompound) | ||
{ | { | ||
super.writeToNBT(par1NBTTagCompound); | super.writeToNBT(par1NBTTagCompound); | ||
− | + | ||
//燃焼時間や調理時間などの書き込み | //燃焼時間や調理時間などの書き込み | ||
par1NBTTagCompound.setShort("BurnTime", (short)this.burnTime); | par1NBTTagCompound.setShort("BurnTime", (short)this.burnTime); | ||
par1NBTTagCompound.setShort("CookTime", (short)this.cookTime); | par1NBTTagCompound.setShort("CookTime", (short)this.cookTime); | ||
− | + | ||
//アイテムの書き込み | //アイテムの書き込み | ||
NBTTagList nbttaglist = new NBTTagList(); | NBTTagList nbttaglist = new NBTTagList(); | ||
− | + | ||
− | for (int i = 0; i < this | + | for (int i = 0; i < this.sampleItemStacks.length; ++i) |
{ | { | ||
− | if (this | + | if (this.sampleItemStacks[i] != null) |
{ | { | ||
NBTTagCompound nbttagcompound1 = new NBTTagCompound(); | NBTTagCompound nbttagcompound1 = new NBTTagCompound(); | ||
nbttagcompound1.setByte("Slot", (byte)i); | nbttagcompound1.setByte("Slot", (byte)i); | ||
− | this | + | this.sampleItemStacks[i].writeToNBT(nbttagcompound1); |
nbttaglist.appendTag(nbttagcompound1); | nbttaglist.appendTag(nbttagcompound1); | ||
} | } | ||
} | } | ||
− | + | ||
par1NBTTagCompound.setTag("Items", nbttaglist); | par1NBTTagCompound.setTag("Items", nbttaglist); | ||
− | + | ||
} | } | ||
− | + | ||
− | public | + | @Override |
− | + | public Packet getDescriptionPacket() { | |
− | + | NBTTagCompound nbtTagCompound = new NBTTagCompound(); | |
− | + | this.writeToNBT(nbtTagCompound); | |
− | + | return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, nbtTagCompound); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
− | + | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
@Override | @Override | ||
− | + | public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) { | |
− | + | this.readFromNBT(pkt.data); | |
− | + | } | |
− | + | ||
− | |||
− | |||
//かまどの処理 | //かまどの処理 | ||
@SideOnly(Side.CLIENT) | @SideOnly(Side.CLIENT) | ||
302行目: | 270行目: | ||
return this.cookTime * par1 / 200; | return this.cookTime * par1 / 200; | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
@SideOnly(Side.CLIENT) | @SideOnly(Side.CLIENT) | ||
311行目: | 279行目: | ||
this.currentItemBurnTime = 200; | this.currentItemBurnTime = 200; | ||
} | } | ||
− | + | ||
return this.burnTime * par1 / this.currentItemBurnTime; | return this.burnTime * par1 / this.currentItemBurnTime; | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
public boolean isBurning() | public boolean isBurning() | ||
320行目: | 288行目: | ||
return this.burnTime > 0; | return this.burnTime > 0; | ||
} | } | ||
− | + | ||
//更新時に呼び出される | //更新時に呼び出される | ||
//かまどの処理 | //かまどの処理 | ||
327行目: | 295行目: | ||
boolean flag = this.burnTime > 0; | boolean flag = this.burnTime > 0; | ||
boolean flag1 = false; | boolean flag1 = false; | ||
− | + | ||
if (this.burnTime > 0) | if (this.burnTime > 0) | ||
{ | { | ||
--this.burnTime; | --this.burnTime; | ||
} | } | ||
− | + | ||
if (!this.worldObj.isRemote) | if (!this.worldObj.isRemote) | ||
{ | { | ||
if (this.burnTime == 0 && this.canSmelt()) | if (this.burnTime == 0 && this.canSmelt()) | ||
{ | { | ||
− | this.currentItemBurnTime = this.burnTime = getItemBurnTime(this | + | this.currentItemBurnTime = this.burnTime = getItemBurnTime(this.sampleItemStacks[1]); |
− | + | ||
if (this.burnTime > 0) | if (this.burnTime > 0) | ||
{ | { | ||
flag1 = true; | flag1 = true; | ||
− | + | ||
− | if (this | + | if (this.sampleItemStacks[1] != null) |
{ | { | ||
− | --this | + | --this.sampleItemStacks[1].stackSize; |
− | + | ||
− | if (this | + | if (this.sampleItemStacks[1].stackSize == 0) |
{ | { | ||
− | this | + | this.sampleItemStacks[1] = this.sampleItemStacks[1].getItem().getContainerItemStack(this.sampleItemStacks[1]); |
} | } | ||
} | } | ||
} | } | ||
} | } | ||
− | + | ||
if (this.isBurning() && this.canSmelt()) | if (this.isBurning() && this.canSmelt()) | ||
{ | { | ||
++this.cookTime; | ++this.cookTime; | ||
− | + | ||
if (this.cookTime == 200) | if (this.cookTime == 200) | ||
{ | { | ||
370行目: | 338行目: | ||
this.cookTime = 0; | this.cookTime = 0; | ||
} | } | ||
− | + | ||
if (flag != this.burnTime > 0) | if (flag != this.burnTime > 0) | ||
{ | { | ||
376行目: | 344行目: | ||
} | } | ||
} | } | ||
− | + | ||
if (flag1) | if (flag1) | ||
{ | { | ||
382行目: | 350行目: | ||
} | } | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
private boolean canSmelt() | private boolean canSmelt() | ||
{ | { | ||
− | if (this | + | if (this.sampleItemStacks[0] == null) |
{ | { | ||
return false; | return false; | ||
392行目: | 360行目: | ||
else | else | ||
{ | { | ||
− | ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this | + | ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.sampleItemStacks[0]); |
if (itemstack == null) return false; | if (itemstack == null) return false; | ||
− | if (this | + | if (this.sampleItemStacks[2] == null) return true; |
− | if (!this | + | if (!this.sampleItemStacks[2].isItemEqual(itemstack)) return false; |
− | int result = this | + | int result = this.sampleItemStacks[2].stackSize + itemstack.stackSize; |
− | return (result <= this | + | return (result <= this.getInventoryStackLimit() && result <= itemstack.getMaxStackSize()); |
} | } | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
public void smeltItem() | public void smeltItem() | ||
406行目: | 374行目: | ||
if (this.canSmelt()) | if (this.canSmelt()) | ||
{ | { | ||
− | ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this | + | ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.sampleItemStacks[0]); |
− | + | ||
− | if (this | + | if (this.sampleItemStacks[2] == null) |
{ | { | ||
− | this | + | this.sampleItemStacks[2] = itemstack.copy(); |
} | } | ||
− | else if (this | + | else if (this.sampleItemStacks[2].isItemEqual(itemstack)) |
{ | { | ||
− | this | + | this.sampleItemStacks[2].stackSize += itemstack.stackSize; |
} | } | ||
− | + | ||
− | --this | + | --this.sampleItemStacks[0].stackSize; |
− | + | ||
− | if (this | + | if (this.sampleItemStacks[0].stackSize <= 0) |
{ | { | ||
− | this | + | this.sampleItemStacks[0] = null; |
} | } | ||
} | } | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
public static int getItemBurnTime(ItemStack par0ItemStack) | public static int getItemBurnTime(ItemStack par0ItemStack) | ||
437行目: | 405行目: | ||
int i = par0ItemStack.getItem().itemID; | int i = par0ItemStack.getItem().itemID; | ||
Item item = par0ItemStack.getItem(); | Item item = par0ItemStack.getItem(); | ||
− | + | ||
if (par0ItemStack.getItem() instanceof ItemBlock && Block.blocksList[i] != null) | if (par0ItemStack.getItem() instanceof ItemBlock && Block.blocksList[i] != null) | ||
{ | { | ||
Block block = Block.blocksList[i]; | Block block = Block.blocksList[i]; | ||
− | + | ||
if (block == Block.woodSingleSlab) | if (block == Block.woodSingleSlab) | ||
{ | { | ||
return 150; | return 150; | ||
} | } | ||
− | + | ||
if (block.blockMaterial == Material.wood) | if (block.blockMaterial == Material.wood) | ||
{ | { | ||
return 300; | return 300; | ||
} | } | ||
− | + | ||
− | if (block == Block. | + | if (block == Block.coalBlock) |
{ | { | ||
return 16000; | return 16000; | ||
} | } | ||
} | } | ||
− | + | ||
if (item instanceof ItemTool && ((ItemTool) item).getToolMaterialName().equals("WOOD")) return 200; | 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 ItemSword && ((ItemSword) item).getToolMaterialName().equals("WOOD")) return 200; | ||
469行目: | 437行目: | ||
} | } | ||
} | } | ||
− | + | ||
//かまどの処理 | //かまどの処理 | ||
public static boolean isItemFuel(ItemStack par0ItemStack) | public static boolean isItemFuel(ItemStack par0ItemStack) | ||
{ | { | ||
return getItemBurnTime(par0ItemStack) > 0; | return getItemBurnTime(par0ItemStack) > 0; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
508行目: | 449行目: | ||
return this.sampleItemStacks.length; | return this.sampleItemStacks.length; | ||
} | } | ||
− | + | ||
// インベントリ内の任意のスロットにあるアイテムを取得 | // インベントリ内の任意のスロットにあるアイテムを取得 | ||
@Override | @Override | ||
514行目: | 455行目: | ||
return this.sampleItemStacks[par1]; | return this.sampleItemStacks[par1]; | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public ItemStack decrStackSize(int par1, int par2) { | public ItemStack decrStackSize(int par1, int par2) { | ||
520行目: | 461行目: | ||
{ | { | ||
ItemStack itemstack; | ItemStack itemstack; | ||
− | + | ||
if (this.sampleItemStacks[par1].stackSize <= par2) | if (this.sampleItemStacks[par1].stackSize <= par2) | ||
{ | { | ||
530行目: | 471行目: | ||
{ | { | ||
itemstack = this.sampleItemStacks[par1].splitStack(par2); | itemstack = this.sampleItemStacks[par1].splitStack(par2); | ||
− | + | ||
if (this.sampleItemStacks[par1].stackSize == 0) | if (this.sampleItemStacks[par1].stackSize == 0) | ||
{ | { | ||
this.sampleItemStacks[par1] = null; | this.sampleItemStacks[par1] = null; | ||
} | } | ||
− | + | ||
return itemstack; | return itemstack; | ||
} | } | ||
544行目: | 485行目: | ||
} | } | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public ItemStack getStackInSlotOnClosing(int par1) { | public ItemStack getStackInSlotOnClosing(int par1) { | ||
558行目: | 499行目: | ||
} | } | ||
} | } | ||
− | + | ||
// インベントリ内のスロットにアイテムを入れる | // インベントリ内のスロットにアイテムを入れる | ||
@Override | @Override | ||
public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { | public void setInventorySlotContents(int par1, ItemStack par2ItemStack) { | ||
this.sampleItemStacks[par1] = par2ItemStack; | this.sampleItemStacks[par1] = par2ItemStack; | ||
− | + | ||
if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) | if (par2ItemStack != null && par2ItemStack.stackSize > this.getInventoryStackLimit()) | ||
{ | { | ||
569行目: | 510行目: | ||
} | } | ||
} | } | ||
− | + | ||
// インベントリの名前 | // インベントリの名前 | ||
@Override | @Override | ||
575行目: | 516行目: | ||
return "Sample"; | return "Sample"; | ||
} | } | ||
− | + | ||
// 多言語対応かどうか | // 多言語対応かどうか | ||
@Override | @Override | ||
581行目: | 522行目: | ||
return false; | return false; | ||
} | } | ||
− | + | ||
// インベントリ内のスタック限界値 | // インベントリ内のスタック限界値 | ||
@Override | @Override | ||
587行目: | 528行目: | ||
return 64; | return 64; | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public void onInventoryChanged() { | public void onInventoryChanged() { | ||
− | this | + | this.onInventoryChanged(); |
} | } | ||
− | + | ||
// par1EntityPlayerがTileEntityを使えるかどうか | // par1EntityPlayerがTileEntityを使えるかどうか | ||
@Override | @Override | ||
public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { | public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { | ||
− | return this | + | return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, (double) this.zCoord + 0.5D) <= 64.0D; |
} | } | ||
− | + | ||
@Override | @Override | ||
public void openChest() {} | public void openChest() {} | ||
− | + | ||
@Override | @Override | ||
public void closeChest() {} | public void closeChest() {} | ||
− | + | ||
@Override | @Override | ||
public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) { | public boolean isItemValidForSlot(int par1, ItemStack par2ItemStack) { | ||
− | return par1 == 2 ? false : (par1 == 1 ? this | + | return par1 == 2 ? false : (par1 == 1 ? this.isItemFuel(par2ItemStack) : true); |
} | } | ||
− | + | ||
//ホッパーにアイテムの受け渡しをする際の優先度 | //ホッパーにアイテムの受け渡しをする際の優先度 | ||
@Override | @Override | ||
615行目: | 556行目: | ||
return par1 == 0 ? slots_bottom : (par1 == 1 ? slots_top : slots_sides); | return par1 == 0 ? slots_bottom : (par1 == 1 ? slots_top : slots_sides); | ||
} | } | ||
− | + | ||
//ホッパーからアイテムを入れられるかどうか | //ホッパーからアイテムを入れられるかどうか | ||
@Override | @Override | ||
621行目: | 562行目: | ||
return this.isItemValidForSlot(par1, par2ItemStack); | return this.isItemValidForSlot(par1, par2ItemStack); | ||
} | } | ||
− | + | ||
//隣接するホッパーにアイテムを送れるかどうか | //隣接するホッパーにアイテムを送れるかどうか | ||
@Override | @Override | ||
627行目: | 568行目: | ||
return par3 != 0 || par1 != 1 || par2ItemStack.itemID == Item.bucketEmpty.itemID; | return par3 != 0 || par1 != 1 || par2ItemStack.itemID == Item.bucketEmpty.itemID; | ||
} | } | ||
− | |||
} | } | ||
634行目: | 574行目: | ||
*ContainerSample.java | *ContainerSample.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
import net.minecraft.inventory.Container; | import net.minecraft.inventory.Container; | ||
646行目: | 586行目: | ||
import cpw.mods.fml.relauncher.Side; | import cpw.mods.fml.relauncher.Side; | ||
import cpw.mods.fml.relauncher.SideOnly; | import cpw.mods.fml.relauncher.SideOnly; | ||
− | + | ||
public class ContainerSample extends Container { | public class ContainerSample extends Container { | ||
− | + | ||
private TileEntitySample tileentity; | private TileEntitySample tileentity; | ||
− | + | ||
− | |||
− | |||
private int lastCookTime; | private int lastCookTime; | ||
private int lastBurnTime; | private int lastBurnTime; | ||
private int lastItemBurnTime; | private int lastItemBurnTime; | ||
− | + | ||
public ContainerSample(EntityPlayer player, TileEntitySample par2TileEntity) { | public ContainerSample(EntityPlayer player, TileEntitySample par2TileEntity) { | ||
this.tileentity = par2TileEntity; | this.tileentity = par2TileEntity; | ||
− | + | ||
− | |||
// InventorySampleで追加するインベントリ | // InventorySampleで追加するインベントリ | ||
− | this.addSlotToContainer(new Slot(this. | + | this.addSlotToContainer(new Slot(this.tileentity, 0, 56, 17)); |
− | this.addSlotToContainer(new Slot(this. | + | this.addSlotToContainer(new Slot(this.tileentity, 1, 56, 53)); |
− | this.addSlotToContainer(new SlotFurnace(player, this. | + | this.addSlotToContainer(new SlotFurnace(player, this.tileentity, 2, 116, 35)); |
int i; | int i; | ||
− | + | ||
// 1 ~ 3段目のインベントリ | // 1 ~ 3段目のインベントリ | ||
for (i = 0; i < 3; ++i) | for (i = 0; i < 3; ++i) | ||
675行目: | 612行目: | ||
} | } | ||
} | } | ||
− | + | ||
// 4段目のインベントリ | // 4段目のインベントリ | ||
for (i = 0; i < 9; ++i) | for (i = 0; i < 9; ++i) | ||
682行目: | 619行目: | ||
} | } | ||
} | } | ||
− | + | ||
public void addCraftingToCrafters(ICrafting par1ICrafting) | public void addCraftingToCrafters(ICrafting par1ICrafting) | ||
{ | { | ||
690行目: | 627行目: | ||
par1ICrafting.sendProgressBarUpdate(this, 2, this.tileentity.currentItemBurnTime); | par1ICrafting.sendProgressBarUpdate(this, 2, this.tileentity.currentItemBurnTime); | ||
} | } | ||
− | + | ||
// 更新を送る | // 更新を送る | ||
public void detectAndSendChanges() | public void detectAndSendChanges() | ||
{ | { | ||
super.detectAndSendChanges(); | super.detectAndSendChanges(); | ||
− | + | ||
for (int i = 0; i < this.crafters.size(); ++i) | for (int i = 0; i < this.crafters.size(); ++i) | ||
{ | { | ||
ICrafting icrafting = (ICrafting)this.crafters.get(i); | ICrafting icrafting = (ICrafting)this.crafters.get(i); | ||
− | + | ||
if (this.lastCookTime != this.tileentity.cookTime) | if (this.lastCookTime != this.tileentity.cookTime) | ||
{ | { | ||
icrafting.sendProgressBarUpdate(this, 0, this.tileentity.cookTime); | icrafting.sendProgressBarUpdate(this, 0, this.tileentity.cookTime); | ||
} | } | ||
− | + | ||
if (this.lastBurnTime != this.tileentity.burnTime) | if (this.lastBurnTime != this.tileentity.burnTime) | ||
{ | { | ||
icrafting.sendProgressBarUpdate(this, 1, this.tileentity.burnTime); | icrafting.sendProgressBarUpdate(this, 1, this.tileentity.burnTime); | ||
} | } | ||
− | + | ||
if (this.lastItemBurnTime != this.tileentity.currentItemBurnTime) | if (this.lastItemBurnTime != this.tileentity.currentItemBurnTime) | ||
{ | { | ||
715行目: | 652行目: | ||
} | } | ||
} | } | ||
− | + | ||
this.lastCookTime = this.tileentity.cookTime; | this.lastCookTime = this.tileentity.cookTime; | ||
this.lastBurnTime = this.tileentity.burnTime; | this.lastBurnTime = this.tileentity.burnTime; | ||
this.lastItemBurnTime = this.tileentity.currentItemBurnTime; | this.lastItemBurnTime = this.tileentity.currentItemBurnTime; | ||
} | } | ||
− | + | ||
// 更新する | // 更新する | ||
@SideOnly(Side.CLIENT) | @SideOnly(Side.CLIENT) | ||
729行目: | 666行目: | ||
this.tileentity.cookTime = par2; | this.tileentity.cookTime = par2; | ||
} | } | ||
− | + | ||
if (par1 == 1) | if (par1 == 1) | ||
{ | { | ||
this.tileentity.burnTime = par2; | this.tileentity.burnTime = par2; | ||
} | } | ||
− | + | ||
if (par1 == 2) | if (par1 == 2) | ||
{ | { | ||
740行目: | 677行目: | ||
} | } | ||
} | } | ||
− | + | ||
// InventorySample内のisUseableByPlayerメソッドを参照 | // InventorySample内のisUseableByPlayerメソッドを参照 | ||
@Override | @Override | ||
public boolean canInteractWith(EntityPlayer par1EntityPlayer) { | public boolean canInteractWith(EntityPlayer par1EntityPlayer) { | ||
− | return this. | + | return this.tileentity.isUseableByPlayer(par1EntityPlayer); |
} | } | ||
− | + | ||
// Shiftクリック | // Shiftクリック | ||
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) | public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) | ||
752行目: | 689行目: | ||
ItemStack itemstack = null; | ItemStack itemstack = null; | ||
Slot slot = (Slot)this.inventorySlots.get(par2); | Slot slot = (Slot)this.inventorySlots.get(par2); | ||
− | + | ||
if (slot != null && slot.getHasStack()) | if (slot != null && slot.getHasStack()) | ||
{ | { | ||
ItemStack itemstack1 = slot.getStack(); | ItemStack itemstack1 = slot.getStack(); | ||
itemstack = itemstack1.copy(); | itemstack = itemstack1.copy(); | ||
− | + | ||
//スロット番号が2の時 | //スロット番号が2の時 | ||
if (par2 == 2) | if (par2 == 2) | ||
766行目: | 703行目: | ||
return null; | return null; | ||
} | } | ||
− | + | ||
slot.onSlotChange(itemstack1, itemstack); | slot.onSlotChange(itemstack1, itemstack); | ||
} | } | ||
806行目: | 743行目: | ||
return null; | return null; | ||
} | } | ||
− | + | ||
if (itemstack1.stackSize == 0) | if (itemstack1.stackSize == 0) | ||
{ | { | ||
815行目: | 752行目: | ||
slot.onSlotChanged(); | slot.onSlotChanged(); | ||
} | } | ||
− | + | ||
if (itemstack1.stackSize == itemstack.stackSize) | if (itemstack1.stackSize == itemstack.stackSize) | ||
{ | { | ||
return null; | return null; | ||
} | } | ||
− | + | ||
slot.onPickupFromSlot(par1EntityPlayer, itemstack1); | slot.onPickupFromSlot(par1EntityPlayer, itemstack1); | ||
} | } | ||
− | + | ||
return itemstack; | return itemstack; | ||
} | } | ||
− | + | ||
} | } | ||
833行目: | 770行目: | ||
*GuiSample.java | *GuiSample.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
import net.minecraft.client.gui.inventory.GuiContainer; | import net.minecraft.client.gui.inventory.GuiContainer; | ||
− | |||
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
import net.minecraft.util.ResourceLocation; | import net.minecraft.util.ResourceLocation; | ||
+ | import net.minecraft.util.StatCollector; | ||
import org.lwjgl.opengl.GL11; | import org.lwjgl.opengl.GL11; | ||
− | + | ||
public class GuiSample extends GuiContainer { | public class GuiSample extends GuiContainer { | ||
− | + | ||
private TileEntitySample tileentity; | private TileEntitySample tileentity; | ||
− | private | + | //ResourceLocationの第一引数を付け足してドメインを指定することもできる |
− | + | //例:new ResourceLocation("sample", "textures/gui/container/furnace.png") | |
+ | private static final ResourceLocation GUITEXTURE = new ResourceLocation("textures/gui/container/furnace.png"); | ||
+ | |||
public GuiSample(EntityPlayer player, TileEntitySample par2TileEntity) { | public GuiSample(EntityPlayer player, TileEntitySample par2TileEntity) { | ||
super(new ContainerSample(player, par2TileEntity)); | super(new ContainerSample(player, par2TileEntity)); | ||
this.tileentity = par2TileEntity; | this.tileentity = par2TileEntity; | ||
− | |||
} | } | ||
− | + | ||
@Override | @Override | ||
protected void drawGuiContainerForegroundLayer(int par1, int par2) | protected void drawGuiContainerForegroundLayer(int par1, int par2) | ||
{ | { | ||
//インベントリ名の描画 | //インベントリ名の描画 | ||
− | String s = this. | + | String s = this.tileentity.isInvNameLocalized() ? this.tileentity.getInvName() : StatCollector.translateToLocal(this.tileentity.getInvName()); |
this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752); | this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752); | ||
− | this.fontRenderer.drawString( | + | this.fontRenderer.drawString(StatCollector.translateToLocal("container.inventory"), 8, this.ySize - 96 + 2, 4210752); |
} | } | ||
− | + | ||
@Override | @Override | ||
protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) | protected void drawGuiContainerBackgroundLayer(float par1, int par2, int par3) | ||
{ | { | ||
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); | GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); | ||
− | + | ||
//テクスチャの指定 | //テクスチャの指定 | ||
− | + | this.mc.getTextureManager().bindTexture(GUITEXTURE); | |
− | + | ||
− | this.mc. | ||
− | |||
//かまど描画処理 | //かまど描画処理 | ||
int k = (this.width - this.xSize) / 2; | int k = (this.width - this.xSize) / 2; | ||
877行目: | 813行目: | ||
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); | this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); | ||
int i1; | int i1; | ||
− | + | ||
if (this.tileentity.isBurning()) | if (this.tileentity.isBurning()) | ||
{ | { | ||
883行目: | 819行目: | ||
this.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 2); | this.drawTexturedModalRect(k + 56, l + 36 + 12 - i1, 176, 12 - i1, 14, i1 + 2); | ||
} | } | ||
− | + | ||
i1 = this.tileentity.getCookProgressScaled(24); | i1 = this.tileentity.getCookProgressScaled(24); | ||
this.drawTexturedModalRect(k + 79, l + 34, 176, 14, i1 + 1, 16); | this.drawTexturedModalRect(k + 79, l + 34, 176, 14, i1 + 1, 16); | ||
} | } | ||
− | + | ||
} | } | ||
894行目: | 830行目: | ||
*GuiHandler.java | *GuiHandler.java | ||
<source lang = "java"> | <source lang = "java"> | ||
− | package mods. | + | package mods.samplemod; |
− | + | ||
import net.minecraft.entity.player.EntityPlayer; | import net.minecraft.entity.player.EntityPlayer; | ||
import net.minecraft.tileentity.TileEntity; | import net.minecraft.tileentity.TileEntity; | ||
import net.minecraft.world.World; | import net.minecraft.world.World; | ||
import cpw.mods.fml.common.network.IGuiHandler; | import cpw.mods.fml.common.network.IGuiHandler; | ||
− | + | ||
public class GuiHandler implements IGuiHandler { | public class GuiHandler implements IGuiHandler { | ||
− | + | ||
@Override | @Override | ||
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { | public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { | ||
if (!world.blockExists(x, y, z)) | if (!world.blockExists(x, y, z)) | ||
return null; | return null; | ||
− | + | ||
TileEntity tileentity = world.getBlockTileEntity(x, y, z); | TileEntity tileentity = world.getBlockTileEntity(x, y, z); | ||
if (tileentity instanceof TileEntitySample) { | if (tileentity instanceof TileEntitySample) { | ||
914行目: | 850行目: | ||
return null; | return null; | ||
} | } | ||
− | + | ||
@Override | @Override | ||
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { | public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { | ||
if (!world.blockExists(x, y, z)) | if (!world.blockExists(x, y, z)) | ||
return null; | return null; | ||
− | + | ||
TileEntity tileentity = world.getBlockTileEntity(x, y, z); | TileEntity tileentity = world.getBlockTileEntity(x, y, z); | ||
if (tileentity instanceof TileEntitySample) { | if (tileentity instanceof TileEntitySample) { | ||
926行目: | 862行目: | ||
return null; | return null; | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} | } | ||
1,051行目: | 905行目: | ||
<source lang = "java"> | <source lang = "java"> | ||
− | public | + | @Override |
− | + | public Packet getDescriptionPacket() { | |
− | + | NBTTagCompound nbtTagCompound = new NBTTagCompound(); | |
− | + | this.writeToNBT(nbtTagCompound); | |
− | + | return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, nbtTagCompound); | |
− | + | } | |
− | } | + | |
− | + | @Override | |
− | @Override | + | public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) { |
− | public | + | this.readFromNBT(pkt.data); |
− | { | + | } |
− | |||
− | |||
− | } | ||
</source> | </source> | ||
NBTに保存した情報をパケットで飛ばすことができる。 | NBTに保存した情報をパケットで飛ばすことができる。 |
2014年10月5日 (日) 14:28時点における最新版
この記事は"Minecraft Forge Universal 9.11.1.xxx~"を前提MODとしています。 |
TileEntityの追加[編集]
かまどとほぼ同じ機能を果たすブロックを作る
ソースコード[編集]
- SampleTileEntityCore.java
package mods.samplemod; 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(clientSideRequired = true, serverSideRequired = false) 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.samplemod; 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 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.getSizeInventory(); ++j1) { ItemStack itemstack = tileentity.getStackInSlot(j1); if (itemstack != null) { float f = par1World.rand.nextFloat() * 0.8F + 0.1F; float f1 = par1World.rand.nextFloat() * 0.8F + 0.1F; float f2 = par1World.rand.nextFloat() * 0.8F + 0.1F; while (itemstack.stackSize > 0) { int k1 = par1World.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)par1World.rand.nextGaussian() * f3); entityitem.motionY = (double)((float)par1World.rand.nextGaussian() * f3 + 0.2F); entityitem.motionZ = (double)((float)par1World.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.samplemod; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.ISidedInventory; 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.INetworkManager; import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.Packet132TileEntityData; import net.minecraft.tileentity.TileEntity; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; public class TileEntitySample extends TileEntity implements ISidedInventory { //燃焼時間 public int burnTime; public int currentItemBurnTime; //調理時間 public int cookTime; 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]; @Override public void readFromNBT(NBTTagCompound par1NBTTagCompound) { super.readFromNBT(par1NBTTagCompound); //アイテムの読み込み NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Items"); this.sampleItemStacks = new ItemStack[this.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.sampleItemStacks.length) { this.sampleItemStacks[b0] = ItemStack.loadItemStackFromNBT(nbttagcompound1); } } //燃焼時間や調理時間などの読み込み this.burnTime = par1NBTTagCompound.getShort("BurnTime"); this.cookTime = par1NBTTagCompound.getShort("CookTime"); this.currentItemBurnTime = getItemBurnTime(this.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.sampleItemStacks.length; ++i) { if (this.sampleItemStacks[i] != null) { NBTTagCompound nbttagcompound1 = new NBTTagCompound(); nbttagcompound1.setByte("Slot", (byte)i); this.sampleItemStacks[i].writeToNBT(nbttagcompound1); nbttaglist.appendTag(nbttagcompound1); } } par1NBTTagCompound.setTag("Items", nbttaglist); } @Override public Packet getDescriptionPacket() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); this.writeToNBT(nbtTagCompound); return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, nbtTagCompound); } @Override public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) { this.readFromNBT(pkt.data); } //かまどの処理 @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.sampleItemStacks[1]); if (this.burnTime > 0) { flag1 = true; if (this.sampleItemStacks[1] != null) { --this.sampleItemStacks[1].stackSize; if (this.sampleItemStacks[1].stackSize == 0) { this.sampleItemStacks[1] = this.sampleItemStacks[1].getItem().getContainerItemStack(this.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.sampleItemStacks[0] == null) { return false; } else { ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.sampleItemStacks[0]); if (itemstack == null) return false; if (this.sampleItemStacks[2] == null) return true; if (!this.sampleItemStacks[2].isItemEqual(itemstack)) return false; int result = this.sampleItemStacks[2].stackSize + itemstack.stackSize; return (result <= this.getInventoryStackLimit() && result <= itemstack.getMaxStackSize()); } } //かまどの処理 public void smeltItem() { if (this.canSmelt()) { ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.sampleItemStacks[0]); if (this.sampleItemStacks[2] == null) { this.sampleItemStacks[2] = itemstack.copy(); } else if (this.sampleItemStacks[2].isItemEqual(itemstack)) { this.sampleItemStacks[2].stackSize += itemstack.stackSize; } --this.sampleItemStacks[0].stackSize; if (this.sampleItemStacks[0].stackSize <= 0) { this.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.coalBlock) { 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; } // スロット数 @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.onInventoryChanged(); } // par1EntityPlayerがTileEntityを使えるかどうか @Override public boolean isUseableByPlayer(EntityPlayer par1EntityPlayer) { return this.worldObj.getBlockTileEntity(this.xCoord, this.yCoord, this.zCoord) != this ? false : par1EntityPlayer.getDistanceSq((double) this.xCoord + 0.5D, (double) this.yCoord + 0.5D, (double) this.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.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.samplemod; 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 int lastCookTime; private int lastBurnTime; private int lastItemBurnTime; public ContainerSample(EntityPlayer player, TileEntitySample par2TileEntity) { this.tileentity = par2TileEntity; // InventorySampleで追加するインベントリ this.addSlotToContainer(new Slot(this.tileentity, 0, 56, 17)); this.addSlotToContainer(new Slot(this.tileentity, 1, 56, 53)); this.addSlotToContainer(new SlotFurnace(player, this.tileentity, 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.tileentity.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.samplemod; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.StatCollector; import org.lwjgl.opengl.GL11; public class GuiSample extends GuiContainer { private TileEntitySample tileentity; //ResourceLocationの第一引数を付け足してドメインを指定することもできる //例:new ResourceLocation("sample", "textures/gui/container/furnace.png") private static final ResourceLocation GUITEXTURE = new ResourceLocation("textures/gui/container/furnace.png"); public GuiSample(EntityPlayer player, TileEntitySample par2TileEntity) { super(new ContainerSample(player, par2TileEntity)); this.tileentity = par2TileEntity; } @Override protected void drawGuiContainerForegroundLayer(int par1, int par2) { //インベントリ名の描画 String s = this.tileentity.isInvNameLocalized() ? this.tileentity.getInvName() : StatCollector.translateToLocal(this.tileentity.getInvName()); this.fontRenderer.drawString(s, this.xSize / 2 - this.fontRenderer.getStringWidth(s) / 2, 6, 4210752); this.fontRenderer.drawString(StatCollector.translateToLocal("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); //テクスチャの指定 this.mc.getTextureManager().bindTexture(GUITEXTURE); //かまど描画処理 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.samplemod; 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; } }
解説[編集]
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に保存します。
@Override public Packet getDescriptionPacket() { NBTTagCompound nbtTagCompound = new NBTTagCompound(); this.writeToNBT(nbtTagCompound); return new Packet132TileEntityData(this.xCoord, this.yCoord, this.zCoord, 1, nbtTagCompound); } @Override public void onDataPacket(INetworkManager net, Packet132TileEntityData pkt) { this.readFromNBT(pkt.data); }
NBTに保存した情報をパケットで飛ばすことができる。