IamMaxim Posted April 9, 2016 Share Posted April 9, 2016 I wrote this code: CustomPlayer.java public class CustomPlayer implements IExtendedEntityProperties { public final static String EXT_PROP_NAME = "CustomPlayer"; private final EntityPlayer player; public CustomPlayerInventory inventory; public CustomPlayer(EntityPlayer player) { this.player = player; } public static void register(EntityPlayer player) { player.registerExtendedProperties(CustomPlayer.EXT_PROP_NAME, new CustomPlayer(player)); NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("size", 2); player.getExtendedProperties(CustomPlayer.EXT_PROP_NAME).saveNBTData(compound); } public static CustomPlayer get(EntityPlayer player) { return (CustomPlayer) player.getExtendedProperties(EXT_PROP_NAME); } @Override public void saveNBTData(NBTTagCompound compound) { System.out.println("saveNBTData()"); NBTTagCompound properties = new NBTTagCompound(); int size = compound.getInteger("size"); properties.setInteger("size", size); properties.setTag(EXT_PROP_NAME, compound); if (inventory == null) inventory = new CustomPlayerInventory(size); this.inventory.writeToNBT(properties); } @Override public void loadNBTData(NBTTagCompound compound) { System.out.println("loadNBTData(); compound == null: " + (compound == null)); NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME); inventory = new CustomPlayerInventory(compound.getInteger("size")); this.inventory.readFromNBT(properties); } @Override public void init(Entity entity, World world) { } } CustomPlayerInventory.java public class CustomPlayerInventory implements IInventory { private ItemStack[] inventory; private String name = "Inventory"; public CustomPlayerInventory(int size) { inventory = new ItemStack[6 + size]; } public boolean isInvNameLocalized() { return name.length() > 0; } @Override public int getSizeInventory() { return inventory.length; } @Override public ItemStack getStackInSlot(int slot) { // System.out.println("getStackInSlot(); slot: " + slot); if (slot < inventory.length) return inventory[slot]; else return null; } @Override public ItemStack decrStackSize(int slot, int amount) { System.out.println("decrStackSize(); slot: " + slot + " amount: " + amount); ItemStack stack = getStackInSlot(slot); if (stack != null) { if (stack.stackSize > amount) { stack = stack.splitStack(amount); this.markDirty(); } else { setInventorySlotContents(slot, null); } } return stack; } @Override public ItemStack getStackInSlotOnClosing(int slot) { System.out.println("getStackInSlotOnClosing(); slot: " + slot); ItemStack stack = getStackInSlot(slot); setInventorySlotContents(slot, null); return stack; } @Override public void setInventorySlotContents(int slot, ItemStack itemStack) { System.out.println("setInventorySlotContents(); slot: " + slot); if (slot < inventory.length) { this.inventory[slot] = itemStack; if (itemStack != null && itemStack.stackSize > this.getInventoryStackLimit()) { itemStack.stackSize = this.getInventoryStackLimit(); } this.markDirty(); } else { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error occurred. Inventory size: " + inventory.length)); } } @Override public String getInventoryName() { return name; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } public void updateSize(int newSize) { ItemStack[] inv = new ItemStack[newSize]; for (int i = 0; i < newSize; i++) { if (i < getSizeInventory()) inv = inventory; } inventory = inv; } @Override public void markDirty() { for (int i = 0; i < getSizeInventory(); ++i) { if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) { inventory = null; } } } @Override public boolean isUseableByPlayer(EntityPlayer player) { return true; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int slot, ItemStack itemStack) { return true; } public void writeToNBT(NBTTagCompound compound) { NBTTagList items = new NBTTagList(); compound.setInteger("size", getSizeInventory()); 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("CustomPlayerInventory", items); } public void readFromNBT(NBTTagCompound compound) { System.out.println("readFromNBT(); compound == null: " + (compound == null)); NBTTagList items = compound.getTagList("CustomPlayerInventory", 9); for (int i = 0; i < items.tagCount(); ++i) { NBTTagCompound item = (NBTTagCompound) items.getCompoundTagAt(i); byte slot = item.getByte("Slot"); if (slot >= 0 && slot < getSizeInventory()) { inventory[slot] = ItemStack.loadItemStackFromNBT(item); } } } } CustomPlayerContainer.java public class CustomPlayerContainer extends Container { private static final int ARMOR_START = 0, ARMOR_END = 3, HANDS_START = 4, HANDS_END = 5, INV_START = 6; private static int INV_END; InventoryPlayer inventoryPlayer; CustomPlayerInventory customPlayerInventory; @Override public boolean canInteractWith(EntityPlayer player) { return true; } private int size; public CustomPlayerContainer(EntityPlayer player, InventoryPlayer inventoryPlayer, CustomPlayerInventory customPlayerInventory) { this.inventoryPlayer = inventoryPlayer; this.customPlayerInventory = customPlayerInventory; size = customPlayerInventory.getSizeInventory(); INV_END = size-1; addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 0, 10, 10, 0));//helmet addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 1, 10, 29, 1));//chestplate addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 2, 10, 48, 2));//leggings addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 3, 10, 67, 3));//boots addSlotToContainer(new Slot(customPlayerInventory, 4, 29, 29));//hand 1 addSlotToContainer(new Slot(customPlayerInventory, 5, 48, 29));//hand 2 System.out.println("Creating container: " + size + " " + inventorySlots.size()); for (int i = 0; i < size; i++) { addSlotToContainer(new Slot(customPlayerInventory, 6 + i, 29 + i * 19, 10)); } } public void updateSlots() { if (customPlayerInventory.getSizeInventory() > size) { for (int i = size; i < customPlayerInventory.getSizeInventory(); i++) { addSlotToContainer(new Slot(customPlayerInventory, 6 + size, 29 + i * 19, 10)); } } } @Override public ItemStack transferStackInSlot(EntityPlayer player, int par2) { System.out.println("TransferSlot(); par2: " + par2); ItemStack itemstack = null; Slot slot = (Slot) this.inventorySlots.get(par2); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (par2 < HANDS_START) { if (!this.mergeItemStack(itemstack1, HANDS_START, INV_END + 1, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else { 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; } } else if (par2 >= INV_START) { if (!this.mergeItemStack(itemstack1, HANDS_START, HANDS_END + 1, false)) { return null; } } else if (par2 >= HANDS_START && par2 < HANDS_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; } public class ArmorSlot extends Slot { final int armorType; final EntityPlayer player; public ArmorSlot(EntityPlayer player, IInventory inventory, int slot, int x, int y, int armorType) { super(inventory, slot, x, y); this.player = player; this.armorType = armorType; } public int getSlotStackLimit() { return 1; } public boolean isItemValid(ItemStack itemstack) { Item item = (itemstack == null ? null : itemstack.getItem()); return item != null && item.isValidArmor(itemstack, armorType, player); } @SideOnly(Side.CLIENT) public IIcon getBackgroundIconIndex() { return ItemArmor.func_94602_b(this.armorType); } } } according to https://github.com/coolAlias/Forge_Tutorials/blob/master/CustomPlayerInventory.java, but I get this error in console: > [00:14:47] [server thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayer:loadNBTData:48]: loadNBTData(); compound == null: false > [00:14:47] [server thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:readFromNBT:158]: readFromNBT(); compound == null: true > [00:14:47] [server thread/ERROR] [FML]: Failed to load extended properties for CustomPlayer. This is a mod issue. > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: java.lang.NullPointerException > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at ru.iammaxim.tesitems.Player.CustomPlayerInventory.readFromNBT(CustomPlayerInventory.java:159) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at ru.iammaxim.tesitems.Player.CustomPlayer.loadNBTData(CustomPlayer.java:51) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.entity.Entity.func_70020_e(Entity.java:1419) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.management.ServerConfigurationManager.func_72380_a(ServerConfigurationManager.java:256) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.management.ServerConfigurationManager.initializeConnectionToPlayer(ServerConfigurationManager.java:114) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at cpw.mods.fml.common.network.handshake.NetworkDispatcher.completeServerSideConnection(NetworkDispatcher.java:190) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at cpw.mods.fml.common.network.handshake.NetworkDispatcher.completeHandshake(NetworkDispatcher.java:463) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at cpw.mods.fml.common.network.internal.HandshakeCompletionHandler.channelRead0(HandshakeCompletionHandler.java:17) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at cpw.mods.fml.common.network.internal.HandshakeCompletionHandler.channelRead0(HandshakeCompletionHandler.java:11) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:98) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.DefaultChannelHandlerContext.invokeChannelRead(DefaultChannelHandlerContext.java:337) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.DefaultChannelHandlerContext.fireChannelRead(DefaultChannelHandlerContext.java:323) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:785) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at io.netty.channel.embedded.EmbeddedChannel.writeInbound(EmbeddedChannel.java:169) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at cpw.mods.fml.common.network.internal.FMLProxyPacket.func_148833_a(FMLProxyPacket.java:77) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:212) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:165) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:659) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:547) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:186) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:427) > [00:14:47] [server thread/INFO] [sTDERR]: [java.lang.Throwable$WrappedPrintStream:println:-1]: at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:685) and empty inventory. So, my question is: Are extended properties saved while exitting world? While I don't exit world, items are saved(or displayed as saved; for now I can't test it) Quote Link to comment Share on other sites More sharing options...
Ernio Posted April 9, 2016 Share Posted April 9, 2016 save/loadNBTData methods are called whenever Entity, IEEP is assigned to, is saved to NBT - that happens when world is dumped on disk, and that happens (actual saving) every "some" ticks or "special actions" - e.g: when on SP and you go to menu, world will be saved. So yes - IEEP is saved inside Entity which is saved inside World. Now, after actually looking at code: YOU DON'T call save/load yourself. Never ever. This is all you need: public class CustomPlayer implements IExtendedEntityProperties { public final static String EXT_PROP_NAME = "CustomPlayer"; private final EntityPlayer player; public CustomPlayerInventory inventory; public CustomPlayer(EntityPlayer player) { this.player = player; } public static void register(EntityPlayer player) { player.registerExtendedProperties(CustomPlayer.EXT_PROP_NAME, new CustomPlayer(player)); } public static CustomPlayer get(EntityPlayer player) { return (CustomPlayer) player.getExtendedProperties(EXT_PROP_NAME); } @Override public void saveNBTData(NBTTagCompound compound) { compound.setInteger("size", inventory.getSomeSize()); } @Override public void loadNBTData(NBTTagCompound compound) { this.inventory = new CustomPlayerInventory(compound.getInteger("size")); } @Override public void init(Entity entity, World world) { } } Obviously in "load" you need to also call inventory.loadFromNBT(parentCompound.getCompoundTag("invTag")). Same (reversed) goes for saving. Additional note: as of 1.8.9+ IEEP is no longer a thing, use Capabilities. Quote 1.7.10 is no longer supported by forge, you are on your own. Link to comment Share on other sites More sharing options...
jabelar Posted April 9, 2016 Share Posted April 9, 2016 save/loadNBTData methods are called whenever Entity, IEEP is assigned to, is saved to NBT - that happens when world is dumped on disk, and that happens (actual saving) every "some" ticks or "special actions" - e.g: when on SP and you go to menu, world will be saved. So yes - IEEP is saved inside Entity which is saved inside World. But only if you override the save / load methods properly. Quote Check out my tutorials here: http://jabelarminecraft.blogspot.com/ Link to comment Share on other sites More sharing options...
IamMaxim Posted April 9, 2016 Author Share Posted April 9, 2016 I tried to edit it, but I get this list of errors: > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerContainer:<init>:44]: Creating container: 8 6 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 0 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 1 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 2 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 3 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 4 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 5 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 6 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 7 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 8 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 9 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 10 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 11 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 12 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > [01:54:28] [Client thread/INFO] [sTDOUT]: [ru.iammaxim.tesitems.Player.CustomPlayerInventory:func_70299_a:70]: setInventorySlotContents(); slot: 13 > [01:54:28] [Client thread/INFO]: [CHAT] Error occurred. Inventory size: 8 > java.lang.IndexOutOfBoundsException: Index: 14, Size: 14 > at java.util.ArrayList.rangeCheck(Unknown Source) ~[?:1.8.0_60] > at java.util.ArrayList.get(Unknown Source) ~[?:1.8.0_60] > at net.minecraft.inventory.Container.func_75139_a(SourceFile:104) ~[zs.class:?] > at net.minecraft.inventory.Container.func_75131_a(SourceFile:390) ~[zs.class:?] > at net.minecraft.client.network.NetHandlerPlayClient.func_147241_a(NetHandlerPlayClient.java:1062) ~[bjb.class:?] > at net.minecraft.network.play.server.S30PacketWindowItems.func_148833_a(SourceFile:49) ~[go.class:?] > at net.minecraft.network.play.server.S30PacketWindowItems.func_148833_a(SourceFile:11) ~[go.class:?] > at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:212) ~[ej.class:?] > at net.minecraft.client.multiplayer.PlayerControllerMP.func_78765_e(PlayerControllerMP.java:273) ~[bje.class:?] > at net.minecraft.client.Minecraft.func_71407_l(Minecraft.java:1602) ~[bao.class:?] > at net.minecraft.client.Minecraft.func_71411_J(Minecraft.java:973) ~[bao.class:?] > at net.minecraft.client.Minecraft.func_99999_d(Minecraft.java:898) [bao.class:?] > at net.minecraft.client.main.Main.main(SourceFile:148) [Main.class:?] > at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_60] > at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_60] > at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_60] > at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_60] > at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?] > at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?] and then it crashes with IndexOutOfBoundsException. I don't understand why it call setInventorySlotContents() more than 8 times. Can you explain how it works, because I couldn't get any info from stacktrace, please? Quote Link to comment Share on other sites More sharing options...
IamMaxim Posted April 10, 2016 Author Share Posted April 10, 2016 Thanks for help. I found my bug. it was in NBTTagList items = compound.getTagList("CustomPlayerInventory", compound.getId()); Previously it was NBTTagList items = compound.getTagList("CustomPlayerInventory", 9); (I don't know why ) Quote Link to comment Share on other sites More sharing options...
Ernio Posted April 10, 2016 Share Posted April 10, 2016 Dude... You have no idea what you are doing, do you? Just because it works doesn't mean is is written properly. Post your whole code. compound.getId() return integer-type of NBT where NBTTagCompound equals 10. compound.getTagList("list", nbtTypeOfListElements); - as you can see, yeah, it will cover with 10 since list is NBTTagCompound-based, but if the list was e.g: Strings, then what? Quote 1.7.10 is no longer supported by forge, you are on your own. Link to comment Share on other sites More sharing options...
IamMaxim Posted April 10, 2016 Author Share Posted April 10, 2016 public class CustomPlayerInventory implements IInventory { private ItemStack[] inventory; private String name = "Inventory"; private EntityPlayer player; private int currentItemSlot = 4; public CustomPlayerInventory(EntityPlayer player, int size) { this.player = player; inventory = new ItemStack; } public boolean isInvNameLocalized() { return name.length() > 0; } @Override public int getSizeInventory() { return inventory.length; } @Override public ItemStack getStackInSlot(int slot) { // System.out.println("getStackInSlot(); slot: " + slot); if (slot < inventory.length) return inventory[slot]; else return null; } public int getFirstEmptySlot() { for (int i = 4; i < getSizeInventory(); i++) { if (getStackInSlot(i) == null) return i; } return -1; } public int getFirstItemSlot(Item item) { for (int i = 0; i < getSizeInventory(); i++) { if (inventory != null) if (Item.getIdFromItem(item) == Item.getIdFromItem(inventory.getItem())) { System.out.println(); return i; } } return -1; } public int pickupItem(ItemStack itemStack) { // System.out.println("pickup " + Item.getIdFromItem(itemStack.getItem()) + " " + itemStack.stackSize); int i = getFirstItemSlot(itemStack.getItem()); // System.out.println("I " + i); if (i == -1) i = getFirstEmptySlot(); // System.out.println("I " + i); if (i == -1) return -1; // System.out.println("I " + i); return addItemsToSlot(i, itemStack); } public int addItemsToSlot(int slot, ItemStack itemStack) { ItemStack src = getStackInSlot(slot); if (src != null) { if (Item.getIdFromItem(src.getItem()) != Item.getIdFromItem(itemStack.getItem())) { System.out.println("ERROR! Trying to add items of another type to slot"); return itemStack.stackSize; } if (src.stackSize + itemStack.stackSize <= src.getMaxStackSize()) { src.stackSize += itemStack.stackSize; return 0; } else { src.stackSize = src.getMaxStackSize(); int i = src.stackSize + itemStack.stackSize - src.getMaxStackSize(); itemStack.stackSize = i; int j; while ((j = getFirstEmptySlot()) != -1 && i != 0) { i = addItemsToSlot(j, itemStack); } return i; } } else { setInventorySlotContents(slot, itemStack); return 0; } } @Override public ItemStack decrStackSize(int slot, int amount) { // System.out.println("decrStackSize(); slot: " + slot + " amount: " + amount); ItemStack stack = getStackInSlot(slot); if (stack != null) { if (stack.stackSize > amount) { stack = stack.splitStack(amount); this.markDirty(); } else { setInventorySlotContents(slot, null); } } return stack; } @Override public ItemStack getStackInSlotOnClosing(int slot) { // System.out.println("getStackInSlotOnClosing(); slot: " + slot); ItemStack stack = getStackInSlot(slot); setInventorySlotContents(slot, null); return stack; } @Override public void setInventorySlotContents(int slot, ItemStack itemStack) { if (slot < 4) updateArmor(); // System.out.println("setInventorySlotContents(); slot: " + slot); if (slot < inventory.length) { this.inventory[slot] = itemStack; if (itemStack != null && itemStack.stackSize > this.getInventoryStackLimit()) { itemStack.stackSize = this.getInventoryStackLimit(); } this.markDirty(); } /*else { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Error occurred. Inventory size: " + inventory.length)); }*/ } @Override public String getInventoryName() { return name; } @Override public boolean hasCustomInventoryName() { return false; } @Override public int getInventoryStackLimit() { return 64; } public void updateArmor() { for (int i = 0; i < 4; i++) { player.inventory.armorInventory = getStackInSlot(i); } } public void updateSize(int newSize) { ItemStack[] inv = new ItemStack[newSize]; for (int i = 0; i < newSize; i++) { if (i < getSizeInventory()) inv = inventory; } inventory = inv; } @Override public void markDirty() { updateArmor(); for (int i = 4; i < getSizeInventory(); ++i) { if (getStackInSlot(i) != null && getStackInSlot(i).stackSize == 0) { inventory = null; } } } @Override public boolean isUseableByPlayer(EntityPlayer player) { return true; } @Override public void openInventory() { } @Override public void closeInventory() { } @Override public boolean isItemValidForSlot(int slot, ItemStack itemStack) { return true; } public void writeToNBT(NBTTagCompound compound) { NBTTagList items = new NBTTagList(); compound.setInteger("size", getSizeInventory()); 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("CustomPlayerInventory", items); } public void readFromNBT(NBTTagCompound compound) { // System.out.println("readFromNBT(); compound == null: " + (compound == null)); NBTTagList items = compound.getTagList("CustomPlayerInventory", compound.getId()); for (int i = 0; i < items.tagCount(); ++i) { NBTTagCompound item = (NBTTagCompound) items.getCompoundTagAt(i); byte slot = item.getByte("Slot"); if (slot >= 0 && slot < getSizeInventory()) { inventory[slot] = ItemStack.loadItemStackFromNBT(item); } } } public ItemStack getCurrentItem() { return getStackInSlot(currentItemSlot); } public void changeCurrentItem() { if (currentItemSlot == 4) currentItemSlot = 5; else currentItemSlot = 4; } public void setCurrentItem(int slot) { currentItemSlot = slot; } } public class CustomPlayer implements IExtendedEntityProperties { public final static String EXT_PROP_NAME = "CustomPlayer"; private final EntityPlayer player; public CustomPlayerInventory inventory; public CustomPlayer(EntityPlayer player) { this.player = player; } public static void register(EntityPlayer player) { player.registerExtendedProperties(CustomPlayer.EXT_PROP_NAME, new CustomPlayer(player)); NBTTagCompound compound = new NBTTagCompound(); compound.setInteger("size", 6); player.getExtendedProperties(CustomPlayer.EXT_PROP_NAME).saveNBTData(compound); } public static CustomPlayer get(EntityPlayer player) { return (CustomPlayer) player.getExtendedProperties(EXT_PROP_NAME); } @Override public void saveNBTData(NBTTagCompound compound) { if (inventory == null) { int size = compound.getInteger("size"); inventory = new CustomPlayerInventory(player, size); } NBTTagCompound props = new NBTTagCompound(); compound.setInteger("size", inventory.getSizeInventory()); inventory.writeToNBT(props); compound.setTag(EXT_PROP_NAME, props); } @Override public void loadNBTData(NBTTagCompound compound) { this.inventory = new CustomPlayerInventory(player, compound.getInteger("size")); inventory.readFromNBT(compound.getCompoundTag(EXT_PROP_NAME)); } @Override public void init(Entity entity, World world) {} } public class CustomPlayerContainer extends Container { private static final int ARMOR_START = 0, ARMOR_END = 3, HANDS_START = 4, HANDS_END = 5, INV_START = 6; private static int INV_END; InventoryPlayer inventoryPlayer; CustomPlayerInventory customPlayerInventory; @Override public boolean canInteractWith(EntityPlayer player) { return true; } private int size; public CustomPlayerContainer(EntityPlayer player, InventoryPlayer inventoryPlayer, CustomPlayerInventory customPlayerInventory) { this.inventoryPlayer = inventoryPlayer; this.customPlayerInventory = customPlayerInventory; size = customPlayerInventory.getSizeInventory(); INV_END = size-1; addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 0, 10, 10, 0));//helmet addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 1, 10, 29, 1));//chestplate addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 2, 10, 48, 2));//leggings addSlotToContainer(new ArmorSlot(player, customPlayerInventory, 3, 10, 67, 3));//boots addSlotToContainer(new Slot(customPlayerInventory, 4, 29, 29));//hand 1 addSlotToContainer(new Slot(customPlayerInventory, 5, 48, 29));//hand 2 for (int i = 0; i < size - 6; i++) { addSlotToContainer(new Slot(customPlayerInventory, 6 + i, 29 + i * 19, 10)); } // System.out.println("Creating container: " + size + " " + inventorySlots.size()); } public void updateSlots() { if (customPlayerInventory.getSizeInventory() > size) { for (int i = size; i < customPlayerInventory.getSizeInventory(); i++) { addSlotToContainer(new Slot(customPlayerInventory, 6 + size, 29 + i * 19, 10)); } } } @Override public ItemStack transferStackInSlot(EntityPlayer player, int par2) { // System.out.println("TransferSlot(); par2: " + par2); ItemStack itemstack = null; Slot slot = (Slot) this.inventorySlots.get(par2); if (slot != null && slot.getHasStack()) { ItemStack itemstack1 = slot.getStack(); itemstack = itemstack1.copy(); if (par2 < HANDS_START) { if (!this.mergeItemStack(itemstack1, HANDS_START, INV_END + 1, true)) { return null; } slot.onSlotChange(itemstack1, itemstack); } else { 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; } } else if (par2 >= INV_START) { if (!this.mergeItemStack(itemstack1, HANDS_START, HANDS_END + 1, false)) { return null; } } else if (par2 >= HANDS_START && par2 < HANDS_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; } public class ArmorSlot extends Slot { final int armorType; final EntityPlayer player; public ArmorSlot(EntityPlayer player, IInventory inventory, int slot, int x, int y, int armorType) { super(inventory, slot, x, y); this.player = player; this.armorType = armorType; } public int getSlotStackLimit() { return 1; } public boolean isItemValid(ItemStack itemstack) { Item item = (itemstack == null ? null : itemstack.getItem()); return item != null && item.isValidArmor(itemstack, armorType, player); } @SideOnly(Side.CLIENT) public IIcon getBackgroundIconIndex() { return ItemArmor.func_94602_b(this.armorType); } } } Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.