Hello all,
I want to add an inventory to an entity, like the horse, but the size of a double chest.
How could I do that? (Whith GUI and Container and stuff)
Well, you already mentioned the major code source you will be using. Copy and use stuff from base classes, in this case the horse. That is what modding is about.
@Glenn: The problem is how to use it. How can I open the GUI? The horse uses player.displayGuiHorse, but that gives me an errror with my entity. =(
@StrangeOIne101: I already made a TileEntity.
Robbi Blechdose
The horse code is done horribly. Try use code from villagers in EntityPlayerMP. That's what Im basing mine off, at least.
Of course, the inventory for my entity still isn't working 100%. The client doesn't sync back to the server. So sorry, I can't really help you. If you do find a way, though, please let me know.
I am trying to do the same thing.What I achieve until now is saving an item inside the mob inventory but the client side is not syncing with server side.When I close the world and open again, the item is inside the mob inventory but only at server side... (I have an inventory with only one slot)
This is the code I am using to save and read data from NBT:
/**
* Writes the inventory out as a list of compound tags.
*/
public NBTTagList writeToNBT(NBTTagList par1NBTTagList)
{
int i;
NBTTagCompound nbttagcompound;
for (i = 0; i < this.armorInventory.getSizeInventory(); ++i)
{
if (this.armorInventory.getStackInSlot(i) != null)
{
nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Slot", (byte)(i));
nbttagcompound = this.armorInventory.getStackInSlot(i).writeToNBT(nbttagcompound);
par1NBTTagList.appendTag(nbttagcompound);
}
}
return par1NBTTagList;
}
/**
* Reads from the given tag list and fills the slots in the inventory with the correct items.
*/
public void readFromNBT(NBTTagList par1NBTTagList)
{
this.armorInventory = new InventoryBasic("spiderMotherInventory",true,1);
for (int i = 0; i < par1NBTTagList.tagCount(); ++i)
{
NBTTagCompound nbttagcompound = (NBTTagCompound)par1NBTTagList.tagAt(i);
int j = nbttagcompound.getByte("Slot") & 255;
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound);
if (itemstack != null)
{
this.armorInventory.setInventorySlotContents(j,itemstack);
}
}
}
/**
* (abstract) Protected helper method to write subclass entity data to NBT.
*/
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) {
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setTag("Inventory", this.writeToNBT(new NBTTagList()));
par1NBTTagCompound.setBoolean("Tammed", this.getTammed());
par1NBTTagCompound.setByte("Skin", (byte)this.getSkinGroupIndex().ordinal());
par1NBTTagCompound.setBoolean("isSpecial", this.getIsSpecial());
}
/**
* (abstract) Protected helper method to read subclass entity data from NBT.
*/
@Override
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) {
super.readEntityFromNBT(par1NBTTagCompound);
NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Inventory");
readFromNBT(nbttaglist);
this.setTammed(par1NBTTagCompound.getBoolean("Tammed"));
int s = par1NBTTagCompound.getByte("Skin");
if (s == 0) {
this.setSkinGroupIndex(Methods.getBiomeGroupType(worldObj, this.posX, this.posZ));
} else {
this.setSkinGroupIndex(Methods.biomeGroupType.values()[s]);
}
if (par1NBTTagCompound.getBoolean("isSpecial"))
this.makeSpecial(null);
}
Ok, thanks.
But, sadly, I need an inventory with the size of a double chest. And you told me, the server-client sync isn't working. =(
And how do you open your GUI?
My mod is working, but I am using datawatcher....As I have just only one slot, I am using 2 bytes on datawatcher to save the item ID and the Damage of it... I didn't like this but for now it will save my time.
To open a GUI, you need to create a GuiHandler and register it inside your base module like this:
NetworkRegistry.instance().registerGuiHandler(INSTANCE, new GuiHandler());
The GuiHandler code is something like this:
public class GuiHandler implements IGuiHandler {
//returns an instance of the Container you made earlier
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
switch (id){
case References.OrganizerGUI:
return new ContainerBlockOrganizer(player.inventory,(TileEntityOrganizer) tileEntity, world, x ,y ,z);
case References.XPBankGUI:
return null;
case References.OrganizerSearchGUI:
return new ContainerBlockOrganizerSearch(player.inventory,world, x ,y ,z);
case References.AutoBagGUI:
return new ContainerAutoBag(player.inventory, ItemAutoBag.getBagInventory(player, null), player.getCurrentEquippedItem(), ItemAutoBag.getBagSize(player,null));
case References.RadarGUI:
return null;
}
return null;
}
//returns an instance of the Gui you made earlier
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
TileEntity tileEntity = world.getBlockTileEntity(x, y, z);
switch (id) {
case References.OrganizerGUI:
return new GuiOrganizer(player.inventory, (TileEntityOrganizer) tileEntity);
case References.XPBankGUI:
return new GuiXPBank(player, x, y, z);
case References.OrganizerSearchGUI:
return new GuiOrganizerSearch(player.inventory);
case References.AutoBagGUI:
return new GuiAutoBag(player.inventory, player.getCurrentEquippedItem(), ItemAutoBag.getBagInventory(player, null), ItemAutoBag.getBagSize(player, null));
case References.RadarGUI:
return new GuiRadar(player);
}
return null;
}
}
Do a search in google for the words GuiHandler and you will find a lot of code to help you if you have problems.
In a future, I'll try to make an inventory with a mob an I'll need to research how to figure it out.. So, if somebody knows a clean code to explain how to do this easly, I will appreciate.
Ok, this problem was solved, I was calling the gui from client side instead of verify: if (!worldObj.isRemote)
Minecraft is kidding me... I copied all gui and container classes from another that is working but in this new gui I can't drag Items from slots!
damned...
It just means you aren't opening it correctly. I can post some code later on fixing that. But mind you, I still haven't figured how to get the client to resync back to the server.
1) Tried to use container, tileentity, gui
- Container is ok, Gui is ok, tileentity not functional, I think this is useless
- Mob inventory didn't synchronizing between server and client, actually is ok at server side but is empty at client side
2) Used Datawatcher
- all things are working perfectly, except the GUI Slot are not refreshing when 2 players are using at the same time...dammed..
Conclusion:
I don't want to create a lot of properties, packets, functions to syncronize an inventory, there must be a way to do it easily..
I will start searching for some tutorial or code sample to achieve this...
1) Tried to use container, tileentity, gui
- Container is ok, Gui is ok, tileentity not functional, I think this is useless
- Mob inventory didn't synchronizing between server and client, actually is ok at server side but is empty at client side
2) Used Datawatcher
- all things are working perfectly, except the GUI Slot are not refreshing when 2 players are using at the same time...dammed..
Conclusion:
I don't want to create a lot of properties, packets, functions to syncronize an inventory, there must be a way to do it easily..
I will start searching for some tutorial or code sample to achieve this...
Can somebody help us with this??
If the client doesn't show the items, you aren't opening it correctly. Look in EntityPlayerMP, under "openMerchantGUI". You want the lines that send the packet, the one that addsToCrafters, the ones that create a new windowId, etc. once you got those, test for an instance of EnitityPlayerMP (under the interact method) and then run those lines of code. I don't have the src on me at the moment, sorry, so I can't post code. :/
If the client doesn't show the items, you aren't opening it correctly. Look in EntityPlayerMP, under "openMerchantGUI". You want the lines that send the packet, the one that addsToCrafters, the ones that create a new windowId, etc. once you got those, test for an instance of EnitityPlayerMP (under the interact method) and then run those lines of code. I don't have the src on me at the moment, sorry, so I can't post code. :/
This is complicated. Why do I need to use this code if I am using Forge OpenGui method this way:
Of course this is the default forge method to open a GUI, and the parameters are not what I need. I don't need the X, Y, Z and World objects... I need the Mob Entity and there is no way to do it with forge open gui method.
I am confused.. I am trying this for 4 days... I changed my code a lot of times. I think I really need suport on this lol
I'll keep studying and trying...
hahaha there is something very very funny happening now.
I tested my mod with 2 players on a server and EVERYTHING is working (including the mob texture change when the armor is in inventory).
But when I play Single Player, I can get and put items from and to player inventory, but when I try to get or put item in mob inventory, the behavior is:
1) trying to pick the item from mob inventory
The item disappear
2) trying to put the item in mob inventory
The item appear inn mob slot gui but it continues in mouse cursor dragging it.
3) trying to get the item from mob slot
The item disappear
4) try to get or put item from or to mob inventory using shift key
Same behaviour
Interesting. I would have thought it would have worked the other way around
Also, did you manage to get you GuiHandler working? I found that what you can do is specify the entity id in place of the x parameter (and set the other ones to 0), then through the GuiHanlser, get the instance of the entity from the entity id.
Anyway, can you post your source? I'd really appreciate if I could see it.
This is all code that is working, fell free to use:
please, give me reputation points ---->
The entity code is too large and extends another classes and at final extends the EntityWithInventory. So, I'll post only the part that calls the GUI. This part is inside Interact method of the entity:
EntitySpiderMother_interact:
public boolean interact(EntityPlayer par1EntityPlayer)
{
if (!getTammed()) {
if (lostworldBase.Debug)
if (worldObj.isRemote)
return false;
else {
setTammed(true);
par1EntityPlayer.addChatMessage("debug: mob is tammed now!");
return true;
}
else
return false;
}
if (par1EntityPlayer.isSneaking()) {
if (!worldObj.isRemote) {
this.openInventory(par1EntityPlayer);
return true;
}
}
if (worldObj.isRemote) return super.interact(par1EntityPlayer);
if (par1EntityPlayer.getCurrentEquippedItem() != null && par1EntityPlayer.getCurrentEquippedItem().getItem() instanceof ItemLostWorldArmor && !this.hasArmor()) {
this.setArmor(par1EntityPlayer.getCurrentEquippedItem().copy());
par1EntityPlayer.inventory.setInventorySlotContents(par1EntityPlayer.inventory.currentItem, null);
return true;
}
if (this.getTammed() && (this.riddenByEntity == null))
{
par1EntityPlayer.mountEntity(this);
return true;
}
else
{
return false;
}
}
EntityWithInventory:
package lostworld.entities;
import lostworld.inventory.inventoryMob;
import lostworld.lib.References;
import lostworld.lostworldBase;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
/**
* Created with IntelliJ IDEA.
* User: Sayuri
* Date: 01/01/14
* Time: 18:21
* To change this template use File | Settings | File Templates.
*/
public class EntityWithInventory extends EntityMob {
public int slotCount = 1;
public inventoryMob inventory = new inventoryMob(this, slotCount);
public EntityWithInventory(World world) {
super(world);
}
public void setInvSize(int i) {
slotCount = i;
inventory = new inventoryMob(this, slotCount);
}
public void openInventory(EntityPlayer par1EntityPlayer) {
par1EntityPlayer.openGui(lostworldBase.INSTANCE, References.tammedNameGUI,par1EntityPlayer.worldObj, this.entityId,0,0);
}
public void onDeath(DamageSource damagesource) {
inventory.dropAllItems(); // when dead, drop the armor
super.onDeath(damagesource);
}
public void writeEntityToNBT(NBTTagCompound nbttagcompound) {
super.writeEntityToNBT(nbttagcompound);
nbttagcompound.setTag("Inventory", inventory.writeToNBT(new NBTTagList())); // write the inventory
}
public void readEntityFromNBT(NBTTagCompound nbttagcompound) {
super.readEntityFromNBT(nbttagcompound);
NBTTagList nbttaglist = nbttagcompound.getTagList("Inventory"); // must read inventory
inventory.readFromNBT(nbttaglist);
}
/**
* Called to update the entity's position/logic.
*/
@Override
public void onLivingUpdate() {
if (worldObj.isRemote) {
if (firstSpawn && !this.worldObj.playerEntities.isEmpty()) {
PacketDispatcher.sendPacketToServer(new getEntityInventoryFromServer(this.entityId, null).makePacket());
firstSpawn = false;
}
}
super.onLivingUpdate();
}
}
GuiHandler:
package lostworld.handlers;
import cpw.mods.fml.common.network.IGuiHandler;
import lostworld.entities.EntityWithInventory;
import lostworld.gui.GuiTamedName;
import lostworld.inventory.ContainerSpiderMother;
import lostworld.lib.Methods;
import lostworld.lib.References;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
/**
* Created with IntelliJ IDEA.
* User: Slash
* Date: 4/27/13
* Time: 2:54 PM
*/
public class GuiHandler implements IGuiHandler {
//returns an instance of the Container you made earlier
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
switch (id){
case References.tammedNameGUI:{
EntityWithInventory ent = Methods.findEntityByID(x, player.worldObj.loadedEntityList); // in this case, X contains EntityWithInventory entityID
if (ent != null)
return new ContainerSpiderMother(player.inventory,ent.inventory);
else
return null;
}
}
return null;
}
//returns an instance of the Gui you made earlier
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
switch (id) {
case References.tammedNameGUI:{
EntityWithInventory ent = Methods.findEntityByID(x, player.worldObj.loadedEntityList); // in this case, X contains EntityWithInventory entityID
if (ent != null)
return new GuiTamedName(player, ent);
else
return null;
}
}
return null;
}
}
GuiTamedName:
package lostworld.gui;
import cpw.mods.fml.common.network.PacketDispatcher;
import lostworld.entities.EntitySpiderBase;
import lostworld.entities.EntityWithInventory;
import lostworld.inventory.ContainerSpiderMother;
import lostworld.lib.Resources;
import lostworld.lib.graphics.graphicMethods;
import lostworld.lostworldBase;
import lostworld.network.packets.tammedNamePacket;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.player.EntityPlayer;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
/**
* Created with IntelliJ IDEA.
* User: Slash
* Date: 4/27/13
* Time: 2:58 PM
*/
public class GuiTamedName extends GuiContainer {
private final EntityPlayer player;
private final EntityLiving entity;
private GuiTextField txtName;
private String s[];
public GuiTamedName(EntityPlayer p, EntityWithInventory e) {
super(new ContainerSpiderMother(p.inventory,e.inventory));
this.buttonList.clear();
this.player = p;
this.entity = e;
}
@Override
public void initGui()
{
xSize = 228;
ySize = 183;
Keyboard.enableRepeatEvents(true);
super.initGui();
this.guiLeft = (this.width - this.xSize) / 2;
this.guiTop = (this.height - this.ySize) / 2;
s = new String[] {lostworldBase.slang.get("tammedName")};
txtName = new GuiTextField(fontRenderer, 90, 30, xSize - 10 - 90, 10);
txtName.setMaxStringLength(20);
txtName.setText(!entity.getCustomNameTag().equals("") ? entity.getCustomNameTag() : entity.getEntityName());
//this.buttonList.add(new GuiButton(idxOk, guiLeft + xSize - 10 - 40, ySize - 30, 40, 20, "Ok"));
}
@Override
protected void keyTyped(char par1, int par2) {
if (par2 == 1) super.keyTyped(par1, par2);
/*if (par2 == 1 || par2 == this.mc.gameSettings.keyBindInventory.keyCode)
{
this.mc.thePlayer.closeScreen(); // close the GUI with Inventory key
return;
}*/
txtName.textboxKeyTyped(par1, par2);
}
@Override
protected void mouseClicked(int par1, int par2, int par3) {
super.mouseClicked(par1, par2, par3);
txtName.mouseClicked(par1 - guiLeft, par2 - guiTop, par3);
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
if (!entity.isDead) PacketDispatcher.sendPacketToServer(new tammedNamePacket(txtName.getText(),entity.entityId,inventorySlots.getSlot(0).getStack()).makePacket());
super.onGuiClosed();
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
@Override
protected void drawGuiContainerForegroundLayer(int par1, int par2) {
graphicMethods.draw3DRect(90, 5, xSize - 10 - 90, 21, true, 0x2F, 0x2F, 0xFF, 155);
fontRenderer.drawString(s[0], (90 + (xSize-90)/2) - fontRenderer.getStringWidth(s[0])/2, 6, 0xAFFFA0, true);
fontRenderer.drawString(entity.getEntityName(), (90 + (xSize-90)/2) - fontRenderer.getStringWidth(entity.getEntityName())/2, 16, 0xAFFFA0, true);
txtName.drawTextBox();
// draw the current spider 3D model
graphicMethods.drawEntity(40, 50, 6, guiLeft + 40 - par1, guiTop + 50 - par2, this.entity);
}
/**
* Draw the background layer for the GuiContainer (everything behind the items)
*/
@Override
protected void drawGuiContainerBackgroundLayer(float f, int i, int j) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.renderEngine.func_110577_a(Resources.TAMMED_SPIDER_GUI);
int x = (width - xSize) / 2;
int y = (height - ySize) / 2;
this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize);
}
@Override
public void updateScreen() {
super.updateScreen(); //To change body of overridden methods use File | Settings | File Templates.
if (entity.isDead)
player.closeScreen();
}
}
ContainerSpiderMother:
package lostworld.inventory;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import lostworld.entities.EntitySpiderBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.InventoryBasic;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
/**
* Created with IntelliJ IDEA.
* User: Slash
* Date: 4/27/13
* Time: 2:19 PM
*/
public class ContainerSpiderMother extends Container {
private IInventory invPlayer;
private inventoryMob invSpider;
private final int firstGuiSlotX = 8; // X coord of first Slot
private final int firstGuiSlotY = 70; // Y coord of first Slot
private final int slotSquareSize = 18; // size in pixels
private final int firstPlayerInvSlotX = 35;
private final int firstPlayerInvSlotY = 102;
private final int firstPlayerSlotX = 35;
private final int firstPlayerSlotY = 160;
public ContainerSpiderMother(IInventory playerInventory, inventoryMob inventorymob) {
this.invPlayer = playerInventory;
this.invSpider = inventorymob;
// create slots to player Inventory
layoutContainer();
}
@Override
public boolean canInteractWith(EntityPlayer player) {
return true;//invSpider.isUseableByPlayer(player);
}
// this method is called when the user click on item using shift
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int slot) {
ItemStack stack = null;
Slot slotObject = (Slot) inventorySlots.get(slot);
//null checks and checks if the item can be stacked (maxStackSize > 1)
if (slotObject != null && slotObject.getHasStack()) {
ItemStack stackInSlot = slotObject.getStack();
stack = stackInSlot.copy();
// put the item into player inventory, since it is in the organizer inventory
if (slot < invSpider.getSizeInventory()) {
// MERGEITEMSTACK = Range X to Y-1, true starts at the end, false starts at beginning
if (!this.mergeItemStack(stackInSlot, invSpider.getSizeInventory(), inventorySlots.size(), false)) {
return null;
}
}
//places it into the tileEntity is possible since its in the player inventory
else if (!this.mergeItemStack(stackInSlot, 0, invSpider.getSizeInventory(), false)) {
return null;
}
if (stackInSlot.stackSize == 0) {
slotObject.putStack(null);
} else {
slotObject.onSlotChanged();
}
}
return stack;
}
protected void layoutContainer() {
addSlotToContainer(new SlotSpiderMother(invSpider,0,firstGuiSlotX, firstGuiSlotY));
bindPlayerInventory();
}
protected void bindPlayerInventory() {
// adds second group of slots (player's inventory)
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 9; x++) {
addSlotToContainer(new Slot(invPlayer, x + y * 9 + 9, firstPlayerInvSlotX + x * slotSquareSize, firstPlayerInvSlotY + y * slotSquareSize));
}
}
// adds first group of slots (Player Hands)
for (int i = 0; i < 9; i++) {
addSlotToContainer(new Slot(invPlayer, i, firstPlayerSlotX + i * slotSquareSize, firstPlayerSlotY));
}
}
}
InventoryMob:
package lostworld.inventory;
import lostworld.entities.EntityWithInventory;
import lostworld.items.ItemLostWorldArmor;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
/**
* Created with IntelliJ IDEA.
* User: Sayuri
* Date: 01/01/14
* Time: 18:19
* To change this template use File | Settings | File Templates.
*/
public class inventoryMob implements IInventory {
public ItemStack inventory[];
public EntityWithInventory ent;
public boolean inventoryChanged;
public int slotCount;
public inventoryMob(EntityWithInventory entity, int i)
{
slotCount = i;
inventory = new ItemStack[i];
inventoryChanged = false;
ent = entity;
}
@Override
public ItemStack decrStackSize(int i, int j)
{
ItemStack aitemstack[] = inventory;
if(aitemstack[i] != null)
{
if(aitemstack[i].stackSize <= j)
{
ItemStack itemstack = aitemstack[i];
aitemstack[i] = null;
return itemstack;
}
ItemStack itemstack1 = aitemstack[i].splitStack(j);
if(aitemstack[i].stackSize == 0)
{
aitemstack[i] = null;
}
return itemstack1;
} else
{
return null;
}
}
@Override
public ItemStack getStackInSlotOnClosing(int i) {
return null;
}
@Override
public void setInventorySlotContents(int i, ItemStack itemstack)
{
inventory[i] = itemstack;
}
public NBTTagList writeToNBT(NBTTagList nbttaglist)
{
for(int i = 0; i < inventory.length; i++)
{
if(inventory[i] != null)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Slot", (byte)i);
inventory[i].writeToNBT(nbttagcompound);
nbttaglist.appendTag(nbttagcompound);
}
}
return nbttaglist;
}
public void readFromNBT(NBTTagList nbttaglist)
{
inventory = new ItemStack[inventory.length];
for(int i = 0; i < nbttaglist.tagCount(); i++)
{
NBTTagCompound nbttagcompound = (NBTTagCompound)nbttaglist.tagAt(i);
int j = nbttagcompound.getByte("Slot") & 0xff;
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound);
if(itemstack.getItem() == null)
{
continue;
}
if(j >= 0 && j < inventory.length)
{
inventory[j] = itemstack;
}
}
}
@Override
public int getSizeInventory()
{
return inventory.length;
}
@Override
public ItemStack getStackInSlot(int i)
{
return inventory[i];
}
@Override
public String getInvName()
{
return "inventoryMob";
}
@Override
public boolean isInvNameLocalized() {
return false;
}
@Override
public int getInventoryStackLimit()
{
return 64;
}
@Override
public void onInventoryChanged()
{
inventoryChanged = true;
}
@Override
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
return true;
}
@Override
public void openChest() {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void closeChest() {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
if (itemstack == null || itemstack.getItem() instanceof ItemLostWorldArmor)
return true;
return false;
}
public boolean canInteractWith(EntityPlayer entityplayer)
{
if(ent.isDead)
{
return false;
} else
{
return entityplayer.getDistanceSqToEntity(ent) <= 64D;
}
}
public void dropAllItems()
{
for(int i = 0; i < inventory.length; i++)
{
if(inventory[i] != null)
{
ent.entityDropItem(inventory[i], 0.0F);
inventory[i] = null;
}
}
}
}
SlotSpiderMother:
package lostworld.inventory;
import lostworld.entities.EntitySpiderBase;
import lostworld.items.ItemLostWorldArmor;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class SlotSpiderMother extends Slot {
private EntitySpiderBase entitySpider;
public SlotSpiderMother(IInventory inventory, int slotIndex, int xPos, int yPos) {
super(inventory, slotIndex, xPos, yPos);
}
public boolean isItemValid(ItemStack itemstack) {
return (itemstack == null) || (itemstack.getItem() instanceof ItemLostWorldArmor); // can't place bag inside other bag
}
/**
* Called when the stack in a Slot changes
*/
@Override
public void onSlotChanged() {
super.onSlotChanged(); //To change body of overridden methods use File | Settings | File Templates.
}
}
tammedNamePacket:
package lostworld.network.packets;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import cpw.mods.fml.relauncher.Side;
import lostworld.entities.EntitySpiderBase;
import lostworld.entities.EntityWithInventory;
import lostworld.lib.Methods;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: Slash
* Date: 12/28/13
* Time: 1:29 PM
*/
public class tammedNamePacket extends BasePacket {
protected String name;
protected int itemID;
protected int itemDamage;
protected int entityID;
public tammedNamePacket() {}
public tammedNamePacket(String name, int entityID, ItemStack itemstack) {
this.name = name;
this.entityID = entityID;
if (itemstack == null) {
this.itemDamage = 0;
this.itemID = 0;
} else {
this.itemDamage = itemstack.getItemDamage();
this.itemID = itemstack.itemID;
}
}
@Override
public void write(ByteArrayDataOutput output)
{
output.writeUTF(this.name);
output.writeInt(this.entityID);
output.writeInt(this.itemID);
output.writeInt(this.itemDamage);
}
@Override
public void read(ByteArrayDataInput input)
{
this.name = input.readUTF();
this.entityID = input.readInt();
this.itemID = input.readInt();
this.itemDamage = input.readInt();
}
@Override
public void execute(EntityPlayer player, Side side)
{
List entList = player.worldObj.loadedEntityList;
if (ent != null) ent.setCustomNameTag(this.name);
EntityWithInventory ent = Methods.findEntityByID(this.entityID, entList);
if (ent instanceof EntitySpiderBase) {
if (this.itemID == 0)
((EntitySpiderBase)ent).setArmor(null);
else
((EntitySpiderBase)ent).setArmor(new ItemStack(this.itemID,1,this.itemDamage));
}
}
}
getEntityInventoryFromServer class:
package lostworld.network.packets;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import cpw.mods.fml.common.network.PacketDispatcher;
import cpw.mods.fml.common.network.Player;
import cpw.mods.fml.relauncher.Side;
import lostworld.entities.EntitySpiderBase;
import lostworld.entities.EntityWithInventory;
import lostworld.lib.Methods;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: Slash
* Date: 12/28/13
* Time: 1:29 PM
*/
public class getEntityInventoryFromServer extends BasePacket {
protected int itemID;
protected int itemDamage;
protected int entityID;
public getEntityInventoryFromServer() {}
public getEntityInventoryFromServer(int entityID, ItemStack itemstack) {
this.entityID = entityID;
if (itemstack == null) {
this.itemDamage = 0;
this.itemID = 0;
} else {
this.itemDamage = itemstack.getItemDamage();
this.itemID = itemstack.itemID;
}
}
@Override
public void write(ByteArrayDataOutput output)
{
output.writeInt(this.entityID);
output.writeInt(this.itemID);
output.writeInt(this.itemDamage);
}
@Override
public void read(ByteArrayDataInput input)
{
this.entityID = input.readInt();
this.itemID = input.readInt();
this.itemDamage = input.readInt();
}
@Override
public void execute(EntityPlayer player, Side side)
{
List entList = player.worldObj.loadedEntityList;
EntityWithInventory ent = Methods.findEntityByID(this.entityID, entList);
if (side.isServer()) {
ItemStack itemStack = ent.inventory.getStackInSlot(0);
if (itemStack != null) {
PacketDispatcher.sendPacketToPlayer(new getEntityInventoryFromServer(this.entityID,itemStack).makePacket(),(Player)player);
}
}
if (side.isClient() && this.itemID != 0) {
((EntitySpiderBase)ent).setArmor(new ItemStack(this.itemID, 1, this.itemDamage));
}
}
}
Guys, forget all about... the code is working perfectly... I think the reason was the entityID. Now I am passing it through X parameter in GuiHandler, before I was using a wrong method to do it...
Thanks a lot for this tip StrangeOne101 !!!!
But.... If I leave the world (Quit minecraft), or go to another dimmension, when I come back the mob isn't showing its armor. So... client side is not the same as server side. But when I enter the GUI, everything became ok at client side...
Last Update:
I solved my problem, but I didn't like the way I did (sending packets), because I wish that minecraft do this instead of me.. but... this is the solution:
Inside the EntityWithInventory class, create OnLivingUpdate and put this code inside:
@Override
public void onLivingUpdate() {
if (worldObj.isRemote) {
if (firstSpawn && !this.worldObj.playerEntities.isEmpty()) {
PacketDispatcher.sendPacketToServer(new getEntityInventoryFromServer(this.entityId, null).makePacket());
firstSpawn = false;
}
}
super.onLivingUpdate();
}
This check if the entity is updating for the first time to that player and ask server for itemstack in slot 0 (the armor), and update client side!
I don't know what to do if my next mob has an large inventory... need to send all inventory data by custom packets?
this is SOLVED for me.... thanks everyone that contribute with ideas!!!!
Guys, forget all about... the code is working perfectly... I think the reason was the entityID. Now I am passing it through X parameter in GuiHandler, before I was using a wrong method to do it...
Thanks a lot for this tip StrangeOne101 !!!!
But.... If I leave the world (Quit minecraft), or go to another dimmension, when I come back the mob isn't showing its armor. So... client side is not the same as server side. But when I enter the GUI, everything became ok at client side...
Yeah, that's still my problem. And because I haven't actually tested it on a server yet, does it still sync perfectly server-side?
Also, thanks for posting your code. I've briefly looked through it and the inventory looks so much neater than mine. Unlike you, I didn't actually assign an inventory for my entity but rather just extended IInventory. Would you mind if I did something similar?
I want to add an inventory to an entity, like the horse, but the size of a double chest.
How could I do that? (Whith GUI and Container and stuff)
Robbi Blechdose
@StrangeOIne101: I already made a TileEntity.
Robbi Blechdose
Of course, the inventory for my entity still isn't working 100%. The client doesn't sync back to the server. So sorry, I can't really help you. If you do find a way, though, please let me know.
Good luck!
This is the code I am using to save and read data from NBT:
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
But, sadly, I need an inventory with the size of a double chest. And you told me, the server-client sync isn't working. =(
And how do you open your GUI?
Robbi Blechdose
To open a GUI, you need to create a GuiHandler and register it inside your base module like this:
The GuiHandler code is something like this:
Do a search in google for the words GuiHandler and you will find a lot of code to help you if you have problems.
In a future, I'll try to make an inventory with a mob an I'll need to research how to figure it out.. So, if somebody knows a clean code to explain how to do this easly, I will appreciate.
thanks!
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
Robbi Blechdose
Minecraft is kidding me... I copied all gui and container classes from another that is working but in this new gui I can't drag Items from slots!
damned...
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
1) Tried to use container, tileentity, gui
- Container is ok, Gui is ok, tileentity not functional, I think this is useless
- Mob inventory didn't synchronizing between server and client, actually is ok at server side but is empty at client side
2) Used Datawatcher
- all things are working perfectly, except the GUI Slot are not refreshing when 2 players are using at the same time...dammed..
Conclusion:
I don't want to create a lot of properties, packets, functions to syncronize an inventory, there must be a way to do it easily..
I will start searching for some tutorial or code sample to achieve this...
Can somebody help us with this??
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
This is complicated. Why do I need to use this code if I am using Forge OpenGui method this way:
Of course this is the default forge method to open a GUI, and the parameters are not what I need. I don't need the X, Y, Z and World objects... I need the Mob Entity and there is no way to do it with forge open gui method.
I am confused.. I am trying this for 4 days... I changed my code a lot of times. I think I really need suport on this lol
I'll keep studying and trying...
thanks!
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
I tested my mod with 2 players on a server and EVERYTHING is working (including the mob texture change when the armor is in inventory).
But when I play Single Player, I can get and put items from and to player inventory, but when I try to get or put item in mob inventory, the behavior is:
1) trying to pick the item from mob inventory
The item disappear
2) trying to put the item in mob inventory
The item appear inn mob slot gui but it continues in mouse cursor dragging it.
3) trying to get the item from mob slot
The item disappear
4) try to get or put item from or to mob inventory using shift key
Same behaviour
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
Also, did you manage to get you GuiHandler working? I found that what you can do is specify the entity id in place of the x parameter (and set the other ones to 0), then through the GuiHanlser, get the instance of the entity from the entity id.
Anyway, can you post your source? I'd really appreciate if I could see it.
Thanks
please, give me reputation points ---->
The entity code is too large and extends another classes and at final extends the EntityWithInventory. So, I'll post only the part that calls the GUI. This part is inside Interact method of the entity:
EntitySpiderMother_interact:
EntityWithInventory:
GuiHandler:
GuiTamedName:
ContainerSpiderMother:
InventoryMob:
SlotSpiderMother:
tammedNamePacket:
getEntityInventoryFromServer class:
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
Thanks a lot for this tip StrangeOne101 !!!!
But.... If I leave the world (Quit minecraft), or go to another dimmension, when I come back the mob isn't showing its armor. So... client side is not the same as server side. But when I enter the GUI, everything became ok at client side...
Last Update:
I solved my problem, but I didn't like the way I did (sending packets), because I wish that minecraft do this instead of me.. but... this is the solution:
Inside the EntityWithInventory class, create OnLivingUpdate and put this code inside:
This check if the entity is updating for the first time to that player and ask server for itemstack in slot 0 (the armor), and update client side!
I don't know what to do if my next mob has an large inventory... need to send all inventory data by custom packets?
this is SOLVED for me.... thanks everyone that contribute with ideas!!!!
Want real chalenge and cool mods? My mods:
Amazing Minecraft Mods
†GnR† Slash - Can one man truly make a difference?
Also, thanks for posting your code. I've briefly looked through it and the inventory looks so much neater than mine. Unlike you, I didn't actually assign an inventory for my entity but rather just extended IInventory. Would you mind if I did something similar?
Thanks.