Jump to content

[SOLVED] [1.12.2] Opening a container from the player's inventory, part 2


Recommended Posts

Posted (edited)

Making a new post because the old one is out of date. I'm still working on the same functionality. I have a block with a tile entity that keeps its inventory when broken and held in the player's inventory. It can be carried around and re-placed elsewhere in the world and still keep its inventory. I'm trying to make it so the player can open the block's inventory by right clicking while holding the block in their hand.

 

At the moment, I have the GUI appearing when right clicking from the hot bar, but the block's inventory appears to be empty. I can put things into the inventory, and they persist as long as the block stays in the player's inventory. If I drop the block and pick it back up again, the items I had put in the inventory are gone. After placing the block, its original inventory reappears. So basically I've managed to create a temporary inventory that only works when the block is in the player's inventory, and it doesn't affect the actual block's inventory at all.

 

My code repository is here.

 

My block.

My tile entity.

My Container.

My GUI.

My GuiHandler.

My ItemBlock.

My capability provider.

My custom ItemStackHandler.

Edited by Daeruin
solved
Posted
43 minutes ago, Daeruin said:

and it doesn't affect the actual block's inventory at all.

Two things, you never load the IItemHandler capability with your ItemStacks. And second of all you need to pass your IItemHandler ItemStacks to your block when you place it.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

All I can recommend is stop using the BlockEntityTag hack. Do the following:

  • Make your ItemBlock have the capability that stores your values(check)
  • When the block is broken/harvested create the item and then copy the capability data from the TE to your item's cap.
  • When the item is right-clicked open your container-gui pair with the data pulled from the item's capability(check)
  • When the ItemBlock places your block access it's TE and copy the capability data from the item to the block's TE.

Currently you are storing the TE's data using BlockEntityTag which is completely detached from your capability. 

Posted

Alright, I tried to do what you said. I think you were both basically saying the same thing. The inventory is now synced when placing the block, but not when picking it up. I'm not sure why. I'm loading the capabilities with the list of ItemStacks in essentially the same way in both cases.

 

7 hours ago, V0idWa1k3r said:

All I can recommend is stop using the BlockEntityTag hack. Do the following:

...

Currently you are storing the TE's data using BlockEntityTag which is completely detached from your capability. 

 

I don't see why you are calling BlockEntityTag a hack. That's the key required by ItemBlock#setTileEntityNBT to provide the tile entity with all of its data when the block is placed, including its coordinates. If I don't wrap the NBT data in that tag, how will I provide the tile entity with its data? Are you saying I need to do something custom to set the TE's data? 

Posted
10 minutes ago, Daeruin said:

Are you saying I need to do something custom to set the TE's data?

You should not be dealing with any NBT data at all. You should be sending the data directly to the Capability. And from the capability to the TE.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
7 minutes ago, Animefan8888 said:

You should not be dealing with any NBT data at all. You should be sending the data directly to the Capability. And from the capability to the TE.

 

Did you see my new code? I think that's what I'm doing now when placing and picking up the block. If I need to be doing it a different way, let me know.

 

My block.

 

I still think I need to manually save the tile entity's data to the ItemStack's NBT. Otherwise I will not be able to instantiate the tile entity when the block is being placed. I'm storing more than just a list of ItemStacks with my tile entity.

 

Any idea why the inventory is syncing when placing the block, but not when picking it up?

Posted
22 minutes ago, Daeruin said:

Any idea why the inventory is syncing when placing the block, but not when picking it up?

What does this line print out.

 

Also try printing out the contents of the IItemHandler in the/when created(GuiHandler) Gui and Container.

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted

It prints out the contents of the inventory, just as one would expect. The stacks all seem to be present. When doing it in the GuiHandler for the Container, it shows nothing. The stacks are gone. I’m not at my computer or I would copy it here for you to see. I haven’t tried it on the GUI side yet. 

Posted

When breaking the block:

 

itemStackCapability: 1xitem.apple@0
itemStackCapability: 1xtile.air@0
itemStackCapability: 1xtile.air@0
itemStackCapability: 1xtile.air@0

 

In the GuiHandler:

GuiHandler:getClientGuiElement:149]: Slot 0: 1xtile.air@0
GuiHandler:getClientGuiElement:149]: Slot 1: 1xtile.air@0
GuiHandler:getClientGuiElement:149]: Slot 2: 1xtile.air@0
GuiHandler:getClientGuiElement:149]: Slot 3: 1xtile.air@0

 

GuiHandler:getServerGuiElement:59]: Slot 0: 1xtile.air@0
GuiHandler:getServerGuiElement:59]: Slot 1: 1xtile.air@0
GuiHandler:getServerGuiElement:59]: Slot 2: 1xtile.air@0
GuiHandler:getServerGuiElement:59]: Slot 3: 1xtile.air@0

Posted

I subscribed to several events to try to get snapshots of the block's inventory at various points. It appears that sometime between the player colliding with the EntityItem, and when the ItemStack gets put in their inventory, the capability's ItemStacks are lost. It happens in EntityItem#onCollideWithPlayer, in between ForgeEventFactory#onItemPickup and FML's firePlayerItemPickupEvent. The EntityItem that gets passed into ForgeEventFactory#onItemPickup has the capability's ItemStacks, but the ItemStack that gets passed into FML's firePlayerItemPickupEvent doesn't have the capability's ItemStacks.

 

The ItemStack that gets passed into FML's firePlayerItemPickupEvent is a clone of the EntityItem's ItemStack. Theoretically, the capability should get passed along to the clone. Is it possible that the capability isn't getting serialize correctly during the clone operation?

 

What else could be going wrong here?

Posted

How come I don't have buttons for spoilers or code in my little formatting bar when replying to messages?

 

Here is the place where the capability's ItemStacks seem to get lost:

 

public void onCollideWithPlayer(EntityPlayer entityIn)
{
    if (!this.world.isRemote)
    {
        if (this.pickupDelay > 0) return;
        ItemStack itemstack = this.getItem();
        Item item = itemstack.getItem();
        int i = itemstack.getCount();

// The entity passed in here has the ItemStacks
        int hook = net.minecraftforge.event.ForgeEventFactory.onItemPickup(this, entityIn);
        if (hook < 0) return;
        ItemStack clone = itemstack.copy();

        if (this.pickupDelay <= 0 && (this.owner == null || lifespan - this.age <= 200 || this.owner.equals(entityIn.getName())) && (hook == 1 || i <= 0 || entityIn.inventory.addItemStackToInventory(itemstack) || clone.getCount() > this.getItem().getCount()))
        {
            clone.setCount(clone.getCount() - this.getItem().getCount());

// The stack passed in here doesn't have the ItemStacks
            net.minecraftforge.fml.common.FMLCommonHandler.instance().firePlayerItemPickupEvent(entityIn, this, clone);

            if (itemstack.isEmpty())
            {
                entityIn.onItemPickup(this, i);
                this.setDead();
                itemstack.setCount(i);
            }

            entityIn.addStat(StatList.getObjectsPickedUpStats(item), i);
        }
    }
}
Posted

Just for the heck of it, I created a copy of the ItemStack, right before spawning the EntityItem, and checked to see if the capability's inventory was preserved. It was not.

 

ItemStack#copy looks like it's supposed to maintain capability information in the copy. Am I misreading? Or is my capability somehow set up wrong, so that it doesn't get carried over to the copy?

Posted
4 hours ago, Daeruin said:

Just for the heck of it, I created a copy of the ItemStack, right before spawning the EntityItem, and checked to see if the capability's inventory was preserved. It was not.

 

ItemStack#copy looks like it's supposed to maintain capability information in the copy. Am I misreading? Or is my capability somehow set up wrong, so that it doesn't get carried over to the copy?

Try use ICapabilitySerializable instead of ICapabilityProvider and use the Capabilities getStorage() function to deserialize and serialize the IItemHandler.

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
18 hours ago, Animefan8888 said:

Try use ICapabilitySerializable instead of ICapabilityProvider and use the Capabilities getStorage() function to deserialize and serialize the IItemHandler.

That pretty much went over my head. If I use ICapabilitySerializable instead of ICapabilityProvider, won't I need to write my own serializeNBT and deserializeNBT methods? Where is getStorage() and how do I use it?

Posted
1 minute ago, Daeruin said:

won't I need to write my own serializeNBT and deserializeNBT methods?

Yes.

1 minute ago, Daeruin said:

Where is getStorage() and how do I use it?

CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage().readFrom/writeToNBT

  • Like 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

Posted
9 minutes ago, Animefan8888 said:

Yes.

And how should I do that? Does it even matter what format I use, or should I copy how ItemStackHandler does it? Maybe it would help if I understood how this is supposed to help solve my problem.

Posted
3 minutes ago, Daeruin said:

And how should I do that?

Instead of implementing ICapabilityProvider implement ICapabilitySerializable and in the methods deserialize and serialize call CapabilityItemHandler.ITEM_HANDLER_CAPABILITY.getStorage().readFromNBT and writeToNBT respectively.

5 minutes ago, Daeruin said:

Maybe it would help if I understood how this is supposed to help solve my problem. 

ItemStack#copy() serializes the capability data and if it can't be serialized then it won't be transferred over.

  • Thanks 1

VANILLA MINECRAFT CLASSES ARE THE BEST RESOURCES WHEN MODDING

I will be posting 1.15.2 modding tutorials on this channel. If you want to be notified of it do the normal YouTube stuff like subscribing, ect.

Forge and vanilla BlockState generator.

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.