Jump to content

[Resolved] Itemstack TreeAttributes sync?


Recommended Posts

Hey, fellow modders and authors of such a great API!

I'm struggling with a problem, which I can't find the source of.

When player breaks my block, it's inventory should be saved in dropped Item Attributes. Well, it does, I can confirm it via debug.

Now, when I try to place the block using that item, I only get partial information from the former ItemStacks. Here are the code parts:

OnBlockBroken (everything is saving inside ItemStack::Attributes just fine)

public override void OnBlockBroken(IWorldAccessor world, BlockPos blockPos, IPlayer byPlayer, float dropQuantityMultiplier = 1)
        {
            if (world.Side == EnumAppSide.Server && (byPlayer == null || byPlayer.WorldData.CurrentGameMode != EnumGameMode.Creative))
            {
                ItemStack[] drops = GetDrops(world, blockPos, byPlayer, 1);
                ItemStack droppedItem = null;


                if (drops != null)
                {
                    if(drops.Length > 0)
                    {
                        droppedItem = drops[0].Clone();
                    }
                }

                if (EntityClass != null)
                {
                    BlockEntity entity = world.BlockAccessor.GetBlockEntity(blockPos);
                    if (entity != null)
                    {
                        if (entity is IBlockEntityContainer)
                        {
                            ParcelInventory inv = (ParcelInventory)((IBlockEntityContainer)entity).Inventory;
                            droppedItem.Attributes.SetInt("contentsCount", inv.Slots.Length);
                            for (int i = 0; i < inv.Slots.Length; i++)
                            {
                                ItemStack stack = inv.Slots[i].Itemstack.Clone();
                                droppedItem.Attributes.SetItemstack("slot_" + i, stack);
                            }
                            //droppedItem.Attributes has three Values. First one - is the size of the following ItemStacks, which are two. 
                          
                            world.SpawnItemEntity(droppedItem, new Vec3d(blockPos.X + 0.5, blockPos.Y + 0.5, blockPos.Z + 0.5), null);
                        }
                    }
                }

                world.PlaySoundAt(Sounds?.GetBreakSound(byPlayer), blockPos.X, blockPos.Y, blockPos.Z, byPlayer);
            }

            world.BlockAccessor.SetBlock(0, blockPos);
        }

Debug info from slot_0 (everything is fine - we have an Item here):

image.thumb.png.dfa2f883a9dd6f6a6b7a244848de412a.png

OnBlockPlaced (ItemStack::Attributes gone crazy and lost almost all information about ItemStack beside Id)

public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ItemStack byItemStack = null)
        {
            base.OnBlockPlaced(world, blockPos, byItemStack);
            if (world.Side == EnumAppSide.Server && byItemStack != null)
            {
                int contentsCount = byItemStack.Attributes.GetInt("contentsCount", -1);
                if (contentsCount != -1)
                {
                    if (EntityClass != null)
                    {
                        BlockEntity entity = world.BlockAccessor.GetBlockEntity(blockPos);
                        if (entity != null)
                        {
                            if (entity is IBlockEntityContainer)
                            {
                                ParcelInventory inv = (ParcelInventory)((IBlockEntityContainer)entity).Inventory;
                                for (int i = 0; i < contentsCount; i++)
                                {
                                    ItemStack stack = byItemStack.Attributes.GetItemstack("slot_" + i);
                                    // stack is not a valid ItemStack! Block == null, Item == null ItemAttributes == null!
                                    inv.Slots[i].Itemstack = stack.Clone();
                                    inv.MarkSlotDirty(i);
                                }
                            }
                            entity.MarkDirty(true);
                            world.BlockAccessor.MarkBlockEntityDirty(blockPos);
                        }
                    }
                }
            }
        }

Debug info from stack (NPEs everywhere!):

image.thumb.png.58f42580a69db5e20e1c099c0589cb7b.png

Any ideas?

Edited by ZigTheHedge
Link to comment
Share on other sites

Hi Zig,

what calls OnBlockPlaced there? The player when you place the stack yourself or something else? This item stack looks like it has been saved to disk manually and not fully loaded yet (via stack.ResolveBlockOrItem())

Also I think you are mixing up something there. stack.Attributes is not the same as stack.ItemAttributes

stack.Attributes = Data specific for this item stack that you can set and read at will
stack.ItemAttributes = shorthand for stack.Collectible.Attributes. This is attribute data as loaded from the block- or itemtype json files. In almost all circumstances you'd want this to be a read only data source.

(upload test)
Kodak_CX7530.jpg.ce73a5aebd3a21f32c1416deb3562558.jpg
 

  • Amazing! 1
Link to comment
Share on other sites

Hi, Tyron!

12 minutes ago, Tyron said:

what calls OnBlockPlaced there? The player when you place the stack yourself or something else? This item stack looks like it has been saved to disk manually and not fully loaded yet (via stack.ResolveBlockOrItem())

The player. Regular right click with Item form of Block.

13 minutes ago, Tyron said:

Also I think you are mixing up something there. stack.Attributes is not the same as stack.ItemAttributes

Yeah, I know. The screenshot just showing that stack.ItemAttributes were there during the "save" in OnBlockBroken, and weren't during "load" in OnBlockPlaced. They should serialize via Attributes.SetItemstack, right?

 

Link to comment
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.