I'm making a mod that replaces the standard villager mob with one that allows the player to give/take items to/from villagers. So far the player can give a villager an item and it will render in it's hands. The problem comes when you give a villager an item and log out. When you log back in the item will still be in the villager's inventory (since you can still take the item from it) but it will not render in it's hands. I think it might be a client/server issue and I've tried using packets but nothing seems to work. Here are the affected classes:
EntityBaseVillager class:
public class EntityBaseVillager extends EntityVillager{
//Global Variable Declarations
private int profession;
public InventoryVillager inventory;
public EntityBaseVillager(){
super(null);
}//end default constructor
public EntityBaseVillager(World world){
super(world);
profession = 0;
inventory = new InventoryVillager(this);
}//end constructor
@Override
public boolean interact(EntityPlayer player){
//Local Variable Declarations
ItemStack itemStack = player.inventory.getCurrentItem();
int profID;
boolean takeItemFlag = true;
if(itemStack != null){
if (itemStack.getItem().itemID == Item.emerald.itemID && getRecipes(player) != null){
super.interact(player);
}else if(itemStack.getItem() instanceof ItemPickaxe){
profID = 1;
}else if(itemStack.getItem() instanceof ItemAxe){
profID = 2;
}else if(itemStack.getItem() instanceof ItemHoe){
profID = 3;
}else if(itemStack.getItem() instanceof ItemSpade){
profID = 4;
}else if(itemStack.getItem() instanceof ItemShears){
profID = 5;
}else if(itemStack.getItem().itemID == Block.enchantmentTable.blockID){
profID = 6;
}else if(itemStack.getItem().itemID == Item.compass.itemID){
profID = 7;
}else if(itemStack.getItem() instanceof ItemAnvilBlock){
profID = 8;
}else if(itemStack.getItem() instanceof ItemSword){
profID = 9;
}else if (itemStack.getItem() instanceof ItemBow){
profID = 10;
}else if(itemStack.getItem().itemID == Item.brewingStand.itemID){
profID = 11;
}else if(itemStack.getItem().itemID == Item.fishingRod.itemID){
profID = 12;
}else if(itemStack.getItem().itemID == Item.pocketSundial.itemID){
profID = 13;
}else{
takeItemFlag = false;
}//end if-else
if(takeItemFlag){
takeItemFromPlayer(player);
}//end if
}else{
giveItemToPlayer(player);
}//end if-else
return false;
}//end interact method
public void takeItemFromPlayer(EntityPlayer player){
inventory.setHeldItem(player.inventory.getCurrentItem());
player.destroyCurrentEquippedItem();
}//end takeItemFromPlayer method
public void giveItemToPlayer(EntityPlayer player){
if(inventory.getHeldItem() != null){
player.inventory.addItemStackToInventory(inventory.getHeldItem());
inventory.setHeldItem(null);
}//end if
}//end giveItemToPlayer method
@Override
public ItemStack getHeldItem(){
return inventory.getHeldItem();
}//end getHeldItems method
@Override
public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound){
super.writeEntityToNBT(par1NBTTagCompound);
par1NBTTagCompound.setTag("Inventory", this.inventory.writeToNBT(new NBTTagList()));
}//end writeEntityToNBT method
@Override
public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound){
super.readEntityFromNBT(par1NBTTagCompound);
NBTTagList nbttaglist = par1NBTTagCompound.getTagList("Inventory");
this.inventory.readFromNBT(nbttaglist);
}//end readEntityFromNBT
}//end EntityBaseVillager
InventoryVillager class:
public class InventoryVillager implements IInventory, Serializable{
//Global Variable Declarations
private ItemStack[] mainInventory; //[0] is held item, last 4 are armor
private ItemStack[] armorInventory;
String inventoryTitle;
public EntityBaseVillager owner;
InventoryVillager(EntityBaseVillager villager){
// inventoryTitle = title;
mainInventory = new ItemStack[getSizeInventory()];
armorInventory = new ItemStack[4];
owner = villager;
}//end constructor
@Override
public int getSizeInventory(){
return 32;
}//end getSizeInventory method
@Override
public void onInventoryChanged(){
if (!owner.worldObj.isRemote){
PacketDispatcher.sendPacketToAllPlayers(PacketCreator.createInventoryPacket(owner.entityId, this));
}//end while loop
}//end onInventoryChanged method
public ItemStack getHeldItem(){
return mainInventory[0];
}//end getHeldItem
public void setHeldItem(ItemStack itemStack){
mainInventory[0] = itemStack;
onInventoryChanged();
}//end setHeldItem
public NBTTagList writeToNBT(NBTTagList par1NBTTagList){
//Write Held Item to NBT
if(this.mainInventory[0] != null){
NBTTagCompound nbttagcompound = new NBTTagCompound();
nbttagcompound.setByte("Slot", (byte)0);
this.mainInventory[0].writeToNBT(nbttagcompound);
par1NBTTagList.appendTag(nbttagcompound);
}//end if
return par1NBTTagList;
}//end writeInventoryToNBT
public void readFromNBT(NBTTagList par1NBTTagList){
//Read Held Item from NBT
if(par1NBTTagList.tagCount() > 0){
NBTTagCompound nbttagcompound = (NBTTagCompound)par1NBTTagList.tagAt(0);
ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound);
setHeldItem(itemstack);
}//end if
}//end readInventoryFromNBT
private void writeObject(ObjectOutputStream out) throws IOException{
for (int i = 0; i < getSizeInventory(); i++){
try{
ItemStack stack = mainInventory[i];
out.writeObject(i + ":" + stack.itemID + ":" + stack.stackSize + ":" + stack.getItemDamage());
}catch (NullPointerException e){
out.writeObject(i + ":" + "null");
}catch (ArrayIndexOutOfBoundsException e){
out.writeObject(i + ":" + "null");
}//end try-catch
}//end for loop
}//end writeObject method
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
mainInventory = new ItemStack[getSizeInventory()];
armorInventory = new ItemStack[4];
for (int i = 0; i < getSizeInventory(); i++){
String data = in.readObject().toString();
if (data.contains("null")){
mainInventory[i] = null;
}else{
int itemID = Integer.parseInt(data.split(":")[1]);
int stackSize = Integer.parseInt(data.split(":")[2]);
int damage = Integer.parseInt(data.split(":")[3]);
ItemStack inventoryStack = new ItemStack(itemID, stackSize, damage);
mainInventory[i] = inventoryStack;
}//end if-else
}//end for loop
}//end readObject method
}//end InventoryVillager class
PacketHandler class:
public class PacketHandler implements IPacketHandler{
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player senderPlayer){
try
{
if (packet.channel.equals("HV_INVENTORY")){
System.out.println("Packet Recieved");
handleInventory(packet, senderPlayer);
}//end if
}catch(Throwable e){
e.printStackTrace();
return;
}//end try-catch
}//end onPacketData method
private void handleInventory(Packet250CustomPayload packet, Player senderPlayer) throws NumberFormatException, IOException, ClassNotFoundException{
byte[] data = packet.data;
ByteArrayInputStream byteInput = new ByteArrayInputStream(data);
ObjectInputStream objectInput = new ObjectInputStream(byteInput);
World world = ((EntityPlayer)senderPlayer).worldObj;
//Assign received data.
int entityId = objectInput.readInt();
InventoryVillager inventory = (InventoryVillager)objectInput.readObject();
objectInput.close();
EntityBaseVillager entity = (EntityBaseVillager)world.getEntityByID(entityId);
inventory.owner = entity;
entity.inventory = inventory;
}//end handleInventory method
}//end PacketHandler class
PacketCreator class:
public final class PacketCreator {
public static Packet createInventoryPacket(int entityId, InventoryVillager inventory){
try{
Packet250CustomPayload thePacket = new Packet250CustomPayload();
thePacket.channel = "HV_INVENTORY";
ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
ObjectOutputStream objectOutput = new ObjectOutputStream(byteOutput);
objectOutput.writeInt(entityId);
objectOutput.writeObject(inventory);
objectOutput.close();
thePacket.data = byteOutput.toByteArray();
thePacket.length = thePacket.data.length;
System.out.println("Packet Sent");
return thePacket;
}catch (Throwable e){
return null;
}//end try-catch
}//end createInventoryPacket method
}//end PacketCreator class