Good day, doing your inventory with tabs and have run into a problem. If you switch tab on the inventory(previous) and take the item, it disappears and the console shows this error:
If you switch tabs then everything is fine(without closing the GUI). After reopening the GUI, the problem persists.
Code:
[spoiler=Events]
[embed=425,349]
@SideOnly(Side.CLIENT)
@SubscribeEvent
public void keys(InputEvent.KeyInputEvent e)
{
if(!(mc.playerController.isInCreativeMode())) {
if (mc.gameSettings.keyBindInventory.isPressed())
PacketHandler.NETWORK.sendToServer(new PacketOpenInventory());
}
}
@SubscribeEvent
public void attachCapabilitiesForEntities(final AttachCapabilitiesEvent.Entity event){
final Entity entity = event.getEntity();
if (entity instanceof EntityPlayer)
event.addCapability(CapabilityInventoryProvider.KEY, new CapabilityInventoryProvider((EntityPlayer)entity));
}
@SubscribeEvent
public void onLivingUpdateEvent(final LivingEvent.LivingUpdateEvent event)
{
if (!(event.getEntityLiving() instanceof EntityPlayer))
return;
final EntityPlayer player = (EntityPlayer) event.getEntityLiving();
if (player == null)
return;
}
@SubscribeEvent
public void onDeathEvent(final LivingDeathEvent event)
{
if(event.getEntityLiving() instanceof EntityPlayer)
{
final EntityPlayer player = (EntityPlayer)event.getEntityLiving();
if (!player.worldObj.getGameRules().getBoolean("keepInventory"))
{
final PlayerInventory inventory = player.getCapability(InventoryCapability.CAPABILITY, null);
for(int i = 0; i < inventory.getInventory().getStacks().length; i++)
{
final ItemStack stack = inventory.getInventory().getStacks();
if(stack != null)
{
player.dropItem(stack, true, false);
inventory.getInventory().getStacks() = null;
}
}
}
}
}
@SubscribeEvent
public void onClone(final PlayerEvent.Clone event)
{
if (event.getEntityPlayer().worldObj.getGameRules().getBoolean("keepInventory"))
{
final PlayerInventory inventory = event.getEntityPlayer().getCapability(InventoryCapability.CAPABILITY, null);
final PlayerInventory inventory_original = event.getOriginal().getCapability(InventoryCapability.CAPABILITY, null);
final NBTTagCompound tag = (NBTTagCompound) inventory.writeData();
inventory_original.readData(tag);
}
}
@SubscribeEvent
public void playerLogin(final net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent event)
{
if (!event.player.worldObj.isRemote)
PacketHandler.NETWORK.sendTo(new PacketInventoryToClient((EntityPlayerMP)event.player), (EntityPlayerMP)event.player);
}
@SubscribeEvent
public void playerChangedDimension(final net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent event)
{
if (!event.player.worldObj.isRemote)
PacketHandler.NETWORK.sendTo(new PacketInventoryToClient((EntityPlayerMP)event.player), (EntityPlayerMP)event.player);
}
@SubscribeEvent
public void incomingPlayer(final PlayerEvent.StartTracking e)
{
if(e.getTarget() instanceof EntityPlayer && e.getEntityPlayer() != null)
PacketHandler.NETWORK.sendTo(new PacketInventoryPlayer((EntityPlayer) e.getTarget()), (EntityPlayerMP) e.getEntityPlayer());
}
[/embed]
[spoiler=Packets]
[embed=425,349]
public class PacketInventoryPlayer implements IMessage
{
public int otherUser;
public ItemStack stack[] = new ItemStack[45];
public PacketInventoryPlayer() {}
public PacketInventoryPlayer(EntityPlayer player) {
PlayerInventory inv = player.getCapability(InventoryCapability.CAPABILITY, null);
otherUser = player.getEntityId();
for (int i = 0; i < stack.length; i++){
stack = inv.getInventory().getStackInSlot(i);
}
}
@Override
public void fromBytes(ByteBuf buf) {
otherUser = buf.readInt();
for (int i = 0; i < stack.length; i++)
stack = ByteBufUtils.readItemStack(buf);
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(otherUser);
for (int i = 0; i < stack.length; i++)
ByteBufUtils.writeItemStack(buf, stack);
}
public static class PacketInventoryPlayerHandler implements IMessageHandler<PacketInventoryPlayer, IMessage>{
@Override
public IMessage onMessage(PacketInventoryPlayer message,MessageContext ctx) {
Minecraft.getMinecraft().addScheduledTask( ()->{
EntityPlayer other = (EntityPlayer) Witcher.proxy.getClientWorld().getEntityByID(message.otherUser);
if(other != null){
PlayerInventory rpg = other.getCapability(InventoryCapability.CAPABILITY, null);
if(rpg != null)
for (int i = 0; i < message.stack.length; i++)
rpg.getInventory().setStackInSlot(i,message.stack);
else
FMLLog.getLogger().info("packet info. 'inventory' was null. dropping packet");
}else
FMLLog.getLogger().info("packet info. 'other' was null. dropping packet");
});
return null;
}
}
}
public class PacketInventoryToClient implements IMessage {
public ItemStack stack[] = new ItemStack[45];
public PacketInventoryToClient() {
}
public PacketInventoryToClient(EntityPlayer player) {
PlayerInventory inv = player.getCapability(InventoryCapability.CAPABILITY, null);
for(int i = 0; i < stack.length; i ++)
stack = inv.getInventory().getStackInSlot(i);
}
@Override
public void fromBytes(ByteBuf buf) {
for (int i = 0; i < stack.length; i++){
stack = ByteBufUtils.readItemStack(buf);
}
}
@Override
public void toBytes(ByteBuf buf) {
for (int i = 0; i < stack.length; i++) {
ByteBufUtils.writeItemStack(buf, stack);
}
}
public static class PacketInventoryToClientHandler implements IMessageHandler<PacketInventoryToClient, IMessage>{
@Override
public IMessage onMessage(PacketInventoryToClient message,MessageContext ctx) {
Minecraft.getMinecraft().addScheduledTask( ()->{
EntityPlayer player = Witcher.proxy.getClientPlayer();
if(player == null)
return;
PlayerInventory rpg = player.getCapability(InventoryCapability.CAPABILITY, null);
for (int i = 0; i < message.stack.length; i++){
rpg.getInventory().setStackInSlot(i,message.stack);
}
});
return null;
}
}
}
public class PacketInventoryToServer implements IMessage {
public ItemStack stack[] = new ItemStack[45];
public PacketInventoryToServer() {}
public PacketInventoryToServer(EntityPlayer player) {
PlayerInventory inv = player.getCapability(InventoryCapability.CAPABILITY, null);
for(int i = 0; i < stack.length; i ++)
stack = inv.getInventory().getStackInSlot(i);
}
@Override
public void fromBytes(ByteBuf buf) {
for (int i = 0; i < stack.length; i++){
stack = ByteBufUtils.readItemStack(buf);
}
}
@Override
public void toBytes(ByteBuf buf) {
for (int i = 0; i < stack.length; i++) {
ByteBufUtils.writeItemStack(buf, stack);
}
}
public static class HandlerPacketInventoryToServer implements IMessageHandler<PacketInventoryToServer, IMessage>{
@Override
public IMessage onMessage(PacketInventoryToServer message,MessageContext ctx) {
EntityPlayer player = (EntityPlayer)ctx.getServerHandler().playerEntity;
WorldServer server = (WorldServer)player.worldObj;
server.addScheduledTask( ()->{
PlayerInventory rpg = player.getCapability(InventoryCapability.CAPABILITY, null);
for (int i = 0; i < message.stack.length; i++){
rpg.getInventory().setStackInSlot(i,message.stack);
}
EntityTracker tracker = server.getEntityTracker();
for (EntityPlayer entityPlayer : tracker.getTrackingPlayers(player)){
IMessage packet = new PacketInventoryPlayer(player);
PacketHandler.NETWORK.sendTo(packet, (EntityPlayerMP) entityPlayer);
}
});
return null;
}
}
}
public class PacketOpenInventory implements IMessage
{
public PacketOpenInventory() {}
public void fromBytes(ByteBuf buf) {}
public void toBytes(ByteBuf buf) {}
public static class PacketOpenInventoryHandler implements IMessageHandler<PacketOpenInventory, IMessage>
{
public IMessage onMessage(PacketOpenInventory message, MessageContext ctx)
{
((WorldServer)ctx.getServerHandler().playerEntity.worldObj).addScheduledTask(() -> {
EntityPlayerMP player_mp = ctx.getServerHandler().playerEntity;
World world = player_mp.worldObj;
FMLNetworkHandler.openGui(player_mp, Witcher.instance, GuiHandler.INVENTORY_PLAYER, world, (int)player_mp.posX, (int)player_mp.posY, (int)player_mp.posZ);
});
return null;
}
}
}
[/embed]
[spoiler=GuiHandler]
[embed=425,349]
public class GuiHandler implements IGuiHandler
{
public static final int INVENTORY_PLAYER = 0;
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
switch (ID)
{
case INVENTORY_PLAYER:
return new ContainerTabOne(player, player.getCapability(InventoryCapability.CAPABILITY, null));
default: return null;
}
}
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z)
{
switch (ID)
{
case INVENTORY_PLAYER:
return new GuiInventoryPlayer(player, player.getCapability(InventoryCapability.CAPABILITY, null));
default: return null;
}
}
}
[/embed]
[spoiler=Capability]
[embed=425,349]
public class CapabilityInventoryProvider implements ICapabilitySerializable<NBTTagCompound>
{
public static final ResourceLocation KEY = new ResourceLocation(Reference.MODID, "tw_player_inventory");
final PlayerInventory slots = new PlayerInventory();
public CapabilityInventoryProvider(EntityPlayer player){
slots.setPlayer(player);
}
public boolean hasCapability(Capability<?> capability, EnumFacing facing)
{
if (capability == InventoryCapability.CAPABILITY)
return true;
return false;
}
@SuppressWarnings("unchecked")
public <T> T getCapability(Capability<T> capability, EnumFacing facing){
if (capability == InventoryCapability.CAPABILITY)
return (T)slots;
return null;
}
public NBTTagCompound serializeNBT(){
return (NBTTagCompound) InventoryCapability.CAPABILITY.writeNBT(slots, null);
}
public void deserializeNBT(NBTTagCompound nbt){
InventoryCapability.CAPABILITY.readNBT(slots, null, nbt);
}
}
public class InventoryCapability
{
@CapabilityInject(PlayerInventory.class)
public static Capability<PlayerInventory> CAPABILITY;
public void register()
{
CapabilityManager.INSTANCE.register(PlayerInventory.class, new StorageHelper(), new DefaultInstanceFactory());
}
public static class StorageHelper implements Capability.IStorage<PlayerInventory>
{
public NBTBase writeNBT(Capability<PlayerInventory> capability, PlayerInventory instance, EnumFacing side)
{
return instance.writeData();
}
public void readNBT(Capability<PlayerInventory> capability, PlayerInventory instance, EnumFacing side, NBTBase nbt)
{
instance.readData(nbt);
}
}
public static class DefaultInstanceFactory implements Callable<PlayerInventory>
{
public PlayerInventory call() throws Exception {
return new PlayerInventory();
}
}
}
public class PlayerInventory
{
private StackHandler inventory;
private EntityPlayer player;
public PlayerInventory()
{
inventory = new StackHandler(new ItemStack[45]);
}
public EntityPlayer getPlayer()
{
return player;
}
public void setPlayer(EntityPlayer newPlayer)
{
this.player = newPlayer;
}
public StackHandler getInventory()
{
return inventory;
}
public NBTBase writeData()
{
NBTTagCompound tag = getInventory().serializeNBT();
return tag;
}
public void readData(NBTBase nbt)
{
getInventory().deserializeNBT((NBTTagCompound)nbt);
}
}
public class StackHandler extends ItemStackHandler
{
public StackHandler(ItemStack[] stack)
{
super(stack);
}
public ItemStack[] getStacks()
{
return stacks;
}
}
[/embed]
[spoiler=In GuiInventoryPlayer]
[embed=425,349]
private void setCurrentCreativeTab(GuiTabs tab)
{
if (tab == null) return;
int i = selectedTabIndex;
selectedTabIndex = tab.getTabIndex();
ContainerTabOne containerGui = (ContainerTabOne) this.inventorySlots;
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if (tab == GuiTabs.tabInventory)
{
Container container = new ContainerInventoryPlayer(player.inventory, !player.worldObj.isRemote, player);
if (this.originalSlots == null)
{
this.originalSlots = containerGui.inventorySlots;
}
containerGui.inventorySlots = container.inventorySlots;
}
else if (i == GuiTabs.tabInventory.getTabIndex())
{
containerGui.inventorySlots = this.originalSlots;
this.originalSlots = null;
}
}
[/embed]
Also if you have suggestions for improving the code, I'll be glad if you'll help me:)