提供: Minecraft Modding Wiki
この記事は"Minecraft Forge Universal 10.13.0.1197~"を前提MODとしています。 |
目次
インベントリを持つアイテムを追加
IInventoryを使ってアイテムにインベントリを持たせています。
GuiとContainerも使います。
固有情報を持つアイテムを追加するの応用。
ソースコード
InventoryItemCore.java
package tutorial.inventoryitem; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.event.FMLInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.registry.GameRegistry; import net.minecraft.item.Item; @Mod(modid="inventoryItem", name = "Inventory Item", version = "1.0") public class InventoryItemCore { @Mod.Instance("inventoryItem") public static InventoryItemCore instance; public Item inventoryItem; /* GuiHandlerの登録 */ @Mod.EventHandler public void init(FMLInitializationEvent event) { NetworkRegistry.INSTANCE.registerGuiHandler(this, new GuiHandler()); } /* アイテムの登録等 */ @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { inventoryItem = new ItemInventory(); GameRegistry.registerItem(inventoryItem, "inventoryItem"); } }
ItemInventory.java
package tutorial.inventoryitem; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.world.World; public class ItemInventory extends Item { public ItemInventory() { super(); //スタックサイズは1コ this.setMaxStackSize(1); } /* Itemが右クリックされた時のメソッド */ @Override public ItemStack onItemRightClick(ItemStack itemStack, World world, EntityPlayer player) { /* GUIを開く。インスタンス, GUIのID, World, X, Y, Z */ player.openGui(InventoryItemCore.instance, 0, world, (int)player.posX, (int)player.posY, (int)player.posZ); return itemStack; } }
GuiHandler.java
package tutorial.inventoryitem; import cpw.mods.fml.common.network.IGuiHandler; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; public class GuiHandler implements IGuiHandler { /* ServerでGUIが開かれたときに呼ばれる 通常はContainerを生成する。 */ @Override public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if(ID == 0) return new ContainerInventoryItem(player.inventory); return null; } /* ClientでGUIが開かれたときに呼ばれる 通常はGUIを生成する */ @Override public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) { if(ID == 0) return new GuiInventoryItem(player.inventory); return null; } }
GuiInventoryItem.java
package tutorial.inventoryitem; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL11; public class GuiInventoryItem extends GuiContainer { private static final ResourceLocation texture = new ResourceLocation("textures/gui/container/generic_54.png"); public GuiInventoryItem(InventoryPlayer inventoryPlayer) { super(new ContainerInventoryItem(inventoryPlayer)); this.ySize = 222; } /* ChestとかInventoryとか文字を描画する */ @Override protected void drawGuiContainerForegroundLayer(int x, int p_146979_2_) { //描画する文字, X, Y, 色 this.fontRendererObj.drawString("Item Container", 8, 6, 4210752); this.fontRendererObj.drawString("Inventory", 8, this.ySize - 96 + 2, 4210752); } /* 背景の描画 */ @Override protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(texture); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); } }
ContainerInventoryItem.java
package tutorial.inventoryitem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; public class ContainerInventoryItem extends Container { private InventoryItem inventory; public ContainerInventoryItem(InventoryPlayer inventoryPlayer) { inventory = new InventoryItem(inventoryPlayer); inventory.openInventory(); int i = 2 * 18 + 1; for (int j = 0; j < 6; ++j) { for (int k = 0; k < 9; ++k) { this.addSlotToContainer(new Slot(inventory, k + j * 9, 8 + k * 18, 18 + j * 18)); } } for (int j = 0; j < 3; ++j) { for (int k = 0; k < 9; ++k) { this.addSlotToContainer(new SlotInventoryItem(inventoryPlayer, k + j * 9 + 9, 8 + k * 18, 103 + j * 18 + i)); } } for (int j = 0; j < 9; ++j) { this.addSlotToContainer(new SlotInventoryItem(inventoryPlayer, j, 8 + j * 18, 161 + i)); } } /* Containerが開いてられるか */ @Override public boolean canInteractWith(EntityPlayer p_75145_1_) { return true; } @Override public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int p_82846_2_) { ItemStack itemstack = null; Slot slot = (Slot)this.inventorySlots.get(p_82846_2_); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (p_82846_2_ < this.inventory.getSizeInventory()) { if (!this.mergeItemStack(itemstack1, this.inventory.getSizeInventory(), this.inventorySlots.size(), true)) { return null; } } //シフトクリック時に、このアイテムだったら動かさない。 else if(slot.getStack() != null && slot.getStack().getItem() == InventoryItemCore.instance.inventoryItem) { return null; } else if (!this.mergeItemStack(itemstack1, 0, this.inventory.getSizeInventory(), false)) { return null; } if (itemstack1.stackSize == 0) { slot.putStack((ItemStack)null); } else { slot.onSlotChanged(); } } return itemstack; } /* Containerを閉じるときに呼ばれる */ @Override public void onContainerClosed(EntityPlayer p_75134_1_) { super.onContainerClosed(p_75134_1_); this.inventory.closeInventory(); } }
InventoryItem.java
package tutorial.inventoryitem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; public class InventoryItem implements IInventory { private InventoryPlayer inventoryPlayer; private ItemStack currentItem; private ItemStack[] items; public InventoryItem(InventoryPlayer inventory) { inventoryPlayer = inventory; currentItem = inventoryPlayer.getCurrentItem(); //InventorySize items = new ItemStack[54]; } @Override public int getSizeInventory() { return items.length; } @Override public ItemStack getStackInSlot(int slot) { return items[slot]; } @Override public ItemStack decrStackSize(int p_70298_1_, int p_70298_2_) { if (this.items[p_70298_1_] != null) { ItemStack itemstack; if (this.items[p_70298_1_].stackSize <= p_70298_2_) { itemstack = this.items[p_70298_1_]; this.items[p_70298_1_] = null; this.markDirty(); return itemstack; } else { itemstack = this.items[p_70298_1_].splitStack(p_70298_2_); if (this.items[p_70298_1_].stackSize == 0) { this.items[p_70298_1_] = null; } this.markDirty(); return itemstack; } } return null; } @Override public ItemStack getStackInSlotOnClosing(int p_70304_1_) { if (this.items[p_70304_1_] != null) { ItemStack itemstack = this.items[p_70304_1_]; this.items[p_70304_1_] = null; return itemstack; } return null; } @Override public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) { this.items[p_70299_1_] = p_70299_2_; if (p_70299_2_ != null && p_70299_2_.stackSize > this.getInventoryStackLimit()) { p_70299_2_.stackSize = this.getInventoryStackLimit(); } this.markDirty(); } @Override public String getInventoryName() { return "InventoryItem"; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } @Override public void markDirty() {} @Override public boolean isUseableByPlayer(EntityPlayer p_70300_1_) { return true; } /* Containerが開かれたタイミングでItemStackの持っているNBTからアイテムを読み込んでいる */ @Override public void openInventory() { if(!currentItem.hasTagCompound()) { currentItem.setTagCompound(new NBTTagCompound()); currentItem.getTagCompound().setTag("Items", new NBTTagList()); } NBTTagList tags = (NBTTagList)currentItem.getTagCompound().getTag("Items"); for(int i = 0; i < tags.tagCount(); i++) { NBTTagCompound tagCompound = tags.getCompoundTagAt(i); int slot = tagCompound.getByte("Slot"); if(slot >= 0 && slot < items.length) { items[slot] = ItemStack.loadItemStackFromNBT(tagCompound); } } } /* Containerを閉じるときに保存 */ @Override public void closeInventory() { NBTTagList tagList = new NBTTagList(); for(int i = 0; i < items.length; i++) { if(items[i] != null) { NBTTagCompound compound = new NBTTagCompound(); compound.setByte("Slot", (byte)i); items[i].writeToNBT(compound); tagList.appendTag(compound); } } ItemStack result = new ItemStack(currentItem.getItem(), 1); result.setTagCompound(new NBTTagCompound()); result.getTagCompound().setTag("Items", tagList); //ItemStackをセットする。NBTは右クリック等のタイミングでしか保存されないため再セットで保存している。 inventoryPlayer.mainInventory[inventoryPlayer.currentItem] = result; } @Override public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) { return true; } }
SlotInventoryItem.java
package tutorial.inventoryitem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; public class SlotInventoryItem extends Slot { public SlotInventoryItem(IInventory p_i1824_1_, int p_i1824_2_, int p_i1824_3_, int p_i1824_4_) { super(p_i1824_1_, p_i1824_2_, p_i1824_3_, p_i1824_4_); } /* このアイテムは動かせない、つかめないようにする。 */ @Override public boolean canTakeStack(EntityPlayer p_82869_1_) { return !(getHasStack() && getStack().getItem() == InventoryItemCore.instance.inventoryItem); } }