It really depends - it could be as simple as storing an integer, or as complex as the vanilla enchantment system, which is actually not a bad place to look for inspiration.
hey just a question regarding your inventories in items tutorials, how would you reference said inventory?
what i mean by that is when doing an inventory check on the player you use player.inventory.getCurrentItem().getItem() instanceof ItemSword for example
If you require the item to be held when used, then create the inventory from player.getHeldItem(), like is done when opening the inventory, and then get either access the slot directly or loop through them, depending on your inventory.
The Meaning of Life, the Universe, and Everything.
Join Date:
5/15/2014
Posts:
43
Member Details
I want to put my armor 3D should do.
import UncelSteve.TutorialMain;
import UncelSteve.item.BaseModItem;
import rpgInventory.RpgInventoryMod;
import rpgInventory.gui.rpginv.PlayerRpgInventory;
import rpgInventory.handlers.oldpackets.PacketInventory;
import rpgInventory.item.armor.ItemRpgInvArmor;
import koonkon.armor3D.item.SamuraiItems;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotCustom extends Slot
{
public int slotIndex;
public EntityPlayer player;
SlotCustom(InventoryCustomPlayer par2IInventory, int par3, int par4,
int par5, EntityPlayer player) {
super(par2IInventory, par3, par4, par5);
this.player = player;
slotIndex = par3;
}
@Override
public boolean canTakeStack(EntityPlayer par1EntityPlayer) {
player = par1EntityPlayer;
return super.canTakeStack(par1EntityPlayer);
}
/**
* Returns the maximum stack size for a given slot (usually the same as
* getInventoryStackLimit(), but 1 in the case of armor slots)
*/
@Override
public int getSlotStackLimit() {
return 1;
}
@Override
public boolean isItemValid(ItemStack par1ItemStack) {
if (par1ItemStack == null)
return true;
if ((par1ItemStack.getItem() instanceof BaseModItem)) {
BaseModItem tmp = (BaseModItem) par1ItemStack.getItem();
switch (slotIndex) {
case 0:
if (tmp.armorType == TutorialMain.ITEMTYPE.NECKLACE)
return true;
return false;
case 1:
if (tmp.armorType == TutorialMain.ITEMTYPE.SHIELD)
return true;
return false;
case 2:
if (tmp.armorType == TutorialMain.ITEMTYPE.CLOAK)
return true;
return false;
case 3:
if (tmp.armorType == TutorialMain.ITEMTYPE.GLOVES)
return true;
return false;
case 4:
if (tmp.armorType == TutorialMain.ITEMTYPE.RING)
return true;
return false;
case 5:
if (tmp.armorType == TutorialMain.ITEMTYPE.RING)
return true;
return false;
case 6:
if (tmp.armorType == TutorialMain.ITEMTYPE.CRYSTAL)
if (par1ItemStack.getItemDamage() > 0)
return true;
return false;
default:
return false;
}
}
return false;
}
@Override
public void onSlotChanged() {
// TODO
// PacketInventory.sendPacket(player, (PlayerRpgInventory)
// this.inventory);
// PacketInventory.sendServerPacket(player);
if (!player.worldObj.isRemote) {
PacketInventory.sendPacket((EntityPlayerMP) player,
PlayerRpgInventory.get(player));
System.out.println("send packet here onslotchanged");
Hi there. i have a problem which is i can't put any item into my custom inventory;
InventoryRPGPlayer.class
package org.mocraft.Inventory;
public class InventoryRPGPlayer implements IInventory
{
/** The name your custom inventory will display in the GUI, possibly just "Inventory" */
private final String name = "Custom Inventory";
/** The key used to store and retrieve the inventory from NBT */
private final String tagName = "CustomInvTag";
/** Define the inventory size here for easy reference */
// This is also the place to define which slot is which if you have different types,
// for example SLOT_SHIELD = 0, SLOT_AMULET = 1;
public static final int INV_SIZE = 2;
/** Inventory's size must be same as number of slots you add to the Container class */
private ItemStack[] inventory = new ItemStack[INV_SIZE];
public InventoryRPGPlayer() {
// don't need anything here!
}
/**
* Makes this inventory an exact replica of the inventory provided
*/
public void copy(InventoryRPGPlayer inv) {
for (int i = 0; i < inv.getSizeInventory(); ++i) {
ItemStack stack = inv.getStackInSlot(i);
inventory[i] = (stack == null ? null : stack.copy());
}
markDirty();
}
@Override
public int getSizeInventory() {
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int slot) {
return inventory[slot];
}
@Override
public ItemStack decrStackSize(int slot, int amount) {
ItemStack stack = getStackInSlot(slot);
if (stack != null) {
if (stack.stackSize > amount) {
stack = stack.splitStack(amount);
markDirty();
} else {
setInventorySlotContents(slot, null);
}
}
return stack;
}
@Override
public ItemStack getStackInSlotOnClosing(int slot) {
ItemStack stack = getStackInSlot(slot);
setInventorySlotContents(slot, null);
return stack;
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack) {
inventory[slot] = stack;
if (stack != null && stack.stackSize > getInventoryStackLimit()) {
stack.stackSize = getInventoryStackLimit();
}
markDirty();
}
@Override
public String getInventoryName() {
return name;
}
@Override
public boolean hasCustomInventoryName() {
return name.length() > 0;
}
/**
* Our custom slots are similar to armor - only one item per slot
*/
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty() {
for (int i = 0; i < getSizeInventory(); ++i) {
if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) {
inventory[i] = null;
}
}
}
@Override
public boolean isUseableByPlayer(EntityPlayer player) {
return true;
}
@Override
public void openInventory() {}
@Override
public void closeInventory() {}
/**
* This method doesn't seem to do what it claims to do, as
* items can still be left-clicked and placed in the inventory
* even when this returns false
*/
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
// If you have different kinds of slots, then check them here:
// if (slot == SLOT_SHIELD && stack.getItem() instanceof ItemShield) return true;
// For now, only ItemUseMana items can be stored in these slots
return false;
}
public void writeToNBT(NBTTagCompound compound) {
NBTTagList items = new NBTTagList();
for (int i = 0; i < getSizeInventory(); ++i) {
if (getStackInSlot(i) != null) {
NBTTagCompound item = new NBTTagCompound();
item.setByte("Slot", (byte) i);
getStackInSlot(i).writeToNBT(item);
items.appendTag(item);
}
}
compound.setTag(tagName, items);
}
public void readFromNBT(NBTTagCompound compound) {
NBTTagList items = compound.getTagList(tagName, compound.getId());
for (int i = 0; i < items.tagCount(); ++i) {
NBTTagCompound item = items.getCompoundTagAt(i);
byte slot = item.getByte("Slot");
if (slot >= 0 && slot < getSizeInventory()) {
inventory[slot] = ItemStack.loadItemStackFromNBT(item);
}
}
}
}
GuiPlayerInventory.class
package org.mocraft.Gui;
@SideOnly(Side.CLIENT)
public class GuiPlayerInventory extends GuiContainer {
private float xSize_lo, ySize_lo;
private static final ResourceLocation texture = new ResourceLocation("mocraftrpg:textures/gui/custom_inventory.png");
/** Could use IInventory type to be more generic, but this way will save an import... */
private final InventoryRPGPlayer inventory;
private EntityPlayer player;
public GuiPlayerInventory(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryRPGPlayer inventoryCustom) {
super(new ContainerRPGPlayer(player, inventoryPlayer, inventoryCustom));
this.inventory = inventoryCustom;
this.player = player;
}
/**
* Draws the screen and all the components in it.
*/
@Override
public void drawScreen(int mouseX, int mouseY, float f) {
super.drawScreen(mouseX, mouseY, f);
xSize_lo = mouseX;
ySize_lo = mouseY;
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) {
// This method will simply draw inventory's name on the screen - you could do without it entirely
// if that's not important to you, since we are overriding the default inventory rather than
// creating a specific type of inventory
String s = inventory.hasCustomInventoryName() ? inventory.getInventoryName() : I18n.format(inventory.getInventoryName());
// with the name "Custom Inventory", the 'Cu' will be drawn in the first slot
fontRendererObj.drawString(s, xSize - fontRendererObj.getStringWidth(s), 12, 4210752);
// this just adds "Inventory" above the player's inventory below
fontRendererObj.drawString(I18n.format("container.inventory"), 80, ySize - 96, 4210752);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
@Override
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
// utilize vanilla drawPlayerModel method:
GuiInventory.func_147046_a(guiLeft + 51, guiTop + 75, 30, guiLeft + 51 - xSize_lo, guiTop + 25 - ySize_lo, mc.thePlayer);
}
}
ContainerRPGPlayer.class
package org.mocraft.Inventory;
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.ItemArmor;
import net.minecraft.item.ItemStack;
public class ContainerRPGPlayer extends Container
{
/** Avoid magic numbers! This will greatly reduce the chance of you making errors in 'transferStackInSlot' method */
private static final int ARMOR_START = InventoryRPGPlayer.INV_SIZE, ARMOR_END = ARMOR_START+3,
INV_START = ARMOR_END+1, INV_END = INV_START+26, HOTBAR_START = INV_END+1, HOTBAR_END = HOTBAR_START+8;
public ContainerRPGPlayer(EntityPlayer player, InventoryPlayer inventoryPlayer, InventoryRPGPlayer inventoryCustom) {
int i;
// Add CUSTOM slots - we'll just add two for now, both of the same type.
// Make a new Slot class for each different item type you want to add
addSlotToContainer(new SlotCustom(inventoryCustom, 0, 80, 8));
addSlotToContainer(new SlotCustom(inventoryCustom, 1, 80, 26));
// Add ARMOR slots; note you need to make a public version of SlotArmor
// just copy and paste the vanilla code into a new class and change what you need
for (i = 0; i < 4; ++i) {
addSlotToContainer(new SlotArmor(player, inventoryPlayer, inventoryPlayer.getSizeInventory() - 1 - i, 8, 8 + i * 18, i));
}
// Add vanilla PLAYER INVENTORY - just copied/pasted from vanilla classes
for (i = 0; i < 3; ++i) {
for (int j = 0; j < 9; ++j) {
addSlotToContainer(new Slot(inventoryPlayer, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
}
}
// Add ACTION BAR - just copied/pasted from vanilla classes
for (i = 0; i < 9; ++i) {
addSlotToContainer(new Slot(inventoryPlayer, i, 8 + i * 18, 142));
}
}
/**
* This should always return true, since custom inventory can be accessed from anywhere
*/
@Override
public boolean canInteractWith(EntityPlayer player) {
return true;
}
/**
* Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
* Basically the same as every other container I make, since I define the same constant indices for all of them
*/
public ItemStack transferStackInSlot(EntityPlayer player, int par2) {
ItemStack itemstack = null;
Slot slot = (Slot) this.inventorySlots.get(par2);
if (slot != null && slot.getHasStack()) {
ItemStack itemstack1 = slot.getStack();
itemstack = itemstack1.copy();
// Either armor slot or custom item slot was clicked
if (par2 < INV_START) {
// try to place in player inventory / action bar
if (!this.mergeItemStack(itemstack1, INV_START, HOTBAR_END + 1, true)) {
return null;
}
slot.onSlotChange(itemstack1, itemstack);
}
// Item is in inventory / hotbar, try to place either in custom or armor slots
else {
// if item is armor
if (itemstack1.getItem() instanceof ItemArmor) {
int type = ((ItemArmor) itemstack1.getItem()).armorType;
if (!this.mergeItemStack(itemstack1, ARMOR_START + type, ARMOR_START + type + 1, false)) {
return null;
}
}
// item in player's inventory, but not in action bar
else if (par2 >= INV_START && par2 < HOTBAR_START) {
// place in action bar
if (!this.mergeItemStack(itemstack1, HOTBAR_START, HOTBAR_START + 1, false)) {
return null;
}
}
// item in action bar - place in player inventory
else if (par2 >= HOTBAR_START && par2 < HOTBAR_END + 1) {
if (!this.mergeItemStack(itemstack1, INV_START, INV_END + 1, false)) {
return null;
}
}
}
if (itemstack1.stackSize == 0) {
slot.putStack((ItemStack) null);
} else {
slot.onSlotChanged();
}
if (itemstack1.stackSize == itemstack.stackSize) {
return null;
}
slot.onPickupFromSlot(player, itemstack1);
}
return itemstack;
}
}
Then are you sure you don't just have your slots in the wrong positions? Do your custom inventory slots highlight when you mouse over them? Can you move items around in the vanilla inventory slots with your custom inventory open?
Show me the code where you actually open the gui. Is it from a key press? For Container-based GUIs, you absolutely must open the gui from the SERVER side, not the client, so you need to send a packet from your key handler if that is the case.
Sorry I missed your comment - if you want your armor to render in 3D, then you will have to make and call a custom item renderer from your gui, rather than the standard methods. I hope you're good with OpenGL, otherwise you can probably forget it.
public KeyManager() {
for(int i = 0; i < 4; ++i) { key = new KeyBinding[i]; }
key[0] = new KeyBinding("Information", Keyboard.KEY_P, "MOCraftRPG");
key[1] = new KeyBinding("Backpack", Keyboard.KEY_B, "MOCraftRPG");
key[2] = new KeyBinding("Skills", Keyboard.KEY_K, "MOCraftRPG");
for(int i = 0; i < key.length; ++i) { ClientRegistry.registerKeyBinding(key[i]);}
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onEvent(KeyInputEvent event) {
EntityPlayer player = (EntityPlayer) Minecraft.getMinecraft().thePlayer;
World world = Minecraft.getMinecraft().theWorld;
int
x = (int)player.posX,
y = (int)player.posY,
z = (int)player.posZ;
Show me the code where you actually open the gui. Is it from a key press? For Container-based GUIs, you absolutely must open the gui from the SERVER side, not the client, so you need to send a packet from your key handler if that is the case.
http://prntscr.com/4sioux Here is a screenshot
what i mean by that is when doing an inventory check on the player you use player.inventory.getCurrentItem().getItem() instanceof ItemSword for example
how do you do a check for this inventory?
import UncelSteve.TutorialMain;
import UncelSteve.item.BaseModItem;
import rpgInventory.RpgInventoryMod;
import rpgInventory.gui.rpginv.PlayerRpgInventory;
import rpgInventory.handlers.oldpackets.PacketInventory;
import rpgInventory.item.armor.ItemRpgInvArmor;
import koonkon.armor3D.item.SamuraiItems;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotCustom extends Slot
{
public int slotIndex;
public EntityPlayer player;
SlotCustom(InventoryCustomPlayer par2IInventory, int par3, int par4,
int par5, EntityPlayer player) {
super(par2IInventory, par3, par4, par5);
this.player = player;
slotIndex = par3;
}
@Override
public boolean canTakeStack(EntityPlayer par1EntityPlayer) {
player = par1EntityPlayer;
return super.canTakeStack(par1EntityPlayer);
}
/**
* Returns the maximum stack size for a given slot (usually the same as
* getInventoryStackLimit(), but 1 in the case of armor slots)
*/
@Override
public int getSlotStackLimit() {
return 1;
}
@Override
public boolean isItemValid(ItemStack par1ItemStack) {
if (par1ItemStack == null)
return true;
if ((par1ItemStack.getItem() instanceof BaseModItem)) {
BaseModItem tmp = (BaseModItem) par1ItemStack.getItem();
switch (slotIndex) {
case 0:
if (tmp.armorType == TutorialMain.ITEMTYPE.NECKLACE)
return true;
return false;
case 1:
if (tmp.armorType == TutorialMain.ITEMTYPE.SHIELD)
return true;
return false;
case 2:
if (tmp.armorType == TutorialMain.ITEMTYPE.CLOAK)
return true;
return false;
case 3:
if (tmp.armorType == TutorialMain.ITEMTYPE.GLOVES)
return true;
return false;
case 4:
if (tmp.armorType == TutorialMain.ITEMTYPE.RING)
return true;
return false;
case 5:
if (tmp.armorType == TutorialMain.ITEMTYPE.RING)
return true;
return false;
case 6:
if (tmp.armorType == TutorialMain.ITEMTYPE.CRYSTAL)
if (par1ItemStack.getItemDamage() > 0)
return true;
return false;
default:
return false;
}
}
return false;
}
@Override
public void onSlotChanged() {
// TODO
// PacketInventory.sendPacket(player, (PlayerRpgInventory)
// this.inventory);
// PacketInventory.sendServerPacket(player);
if (!player.worldObj.isRemote) {
PacketInventory.sendPacket((EntityPlayerMP) player,
PlayerRpgInventory.get(player));
System.out.println("send packet here onslotchanged");
// PacketInventory pack = new PacketInventory();
// PacketPipeline17 pipe = mod_RpgInventory.PIPELINE;
// pipe.sendTo(pack, (EntityPlayerMP) player);
}
super.onSlotChanged();
}
@Override
public void putStack(ItemStack par1ItemStack) {
if (this.inventory != null)
this.inventory.setInventorySlotContents(this.slotIndex,
par1ItemStack);
this.onSlotChanged();
}
// this My Customslot
InventoryRPGPlayer.class
GuiPlayerInventory.class
ContainerRPGPlayer.class
And why not? Can you open your inventory?
Please put each class in [ spoiler ] tags, or use a service like Github or pastebin to make it easier to navigate.
I can open my inventory, but i can put in any item or take.
when i right left click, the item should float up and follow my cursor, but in my case it won't work.
and i did some test:
1) open player inventory gui by key E, and put some items init.
2) open my custom gui, and i see same items in same slots!
and i am sure all of slot show on the gui .
Sorry I missed your comment - if you want your armor to render in 3D, then you will have to make and call a custom item renderer from your gui, rather than the standard methods. I hope you're good with OpenGL, otherwise you can probably forget it.
(It's strange that every time i use [ code ] method, system will eat my reply.)
package org.mocraft.Manager;
import org.lwjgl.input.Keyboard;
import org.mocraft.MOCraftRPG;
import org.mocraft.Proxy.ProxyClient;
import org.mocraft.System.Core;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent.KeyInputEvent;
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class KeyManager {
public static KeyBinding[] key;
public KeyManager() {
for(int i = 0; i < 4; ++i) { key = new KeyBinding[i]; }
key[0] = new KeyBinding("Information", Keyboard.KEY_P, "MOCraftRPG");
key[1] = new KeyBinding("Backpack", Keyboard.KEY_B, "MOCraftRPG");
key[2] = new KeyBinding("Skills", Keyboard.KEY_K, "MOCraftRPG");
for(int i = 0; i < key.length; ++i) { ClientRegistry.registerKeyBinding(key[i]);}
}
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void onEvent(KeyInputEvent event) {
EntityPlayer player = (EntityPlayer) Minecraft.getMinecraft().thePlayer;
World world = Minecraft.getMinecraft().theWorld;
int
x = (int)player.posX,
y = (int)player.posY,
z = (int)player.posZ;
if(key[0].isPressed()) {
player.openGui(MOCraftRPG.instance, Core.GUI_PLAYER_INFORMATION, world, x, y, z);
} else if(key[1].isPressed()) {
player.openGui(MOCraftRPG.instance, Core.GUI_PLAYER_INVENTORY, world, x, y, z);
}
}
}
I don't quiet get it.
sorry about that.
can u explain more about it?
the problem is i open a gui which extends GuiContainer in Clien Side?
For example, searching 'minecraft client server modding' on Google resulted in this excellent article:
http://greyminecraftcoder.blogspot.com/2013/10/client-server-communication-using.html