changing/setting itemId

Hi,
quick question about item ID´s.

Is it possible to change/set the itemID of an item?

Context:
My game requires networking. My current approach is to rebuild the item for my remote players based on the ItemDefinition. But the problem is that the itemID on the remote player doesn't match the itemID on the localplayer. If I for example equip an item I need to somehow reference that item for the remote players and the easiest (safest) way to do that would be to reference the itemID.
 
I see... There is no way of setting the item ID externally right now.

I made the item ID setter internal because I didn't want users to modify IDs themselves, fearing that people could break something if they didn't take all possibilities into account. But your use case makes sense so maybe I should make it public...

The issue is that sometimes I use the item ID as a key to some dictionaries, so changing the ID after the Item is created could cause some issues.

In your use case, are you required to set the Item ID after the items are created on the client, or would a overload function that takes in the itemID the item should have when calling the CreateItem function work for you? something in the likes this:

InventorySystemManager.CreateItem(item/itemDefinition, itemID)
and/or
Item.Create(item/itemDefinition, itemID)

I believe that should work. I could implement that for the next update.

Try adding that to the Item script

Code:
        /// <summary>
        /// Item Constructor.
        /// </summary>
        /// <param name="itemDefinition">The Item Definition.</param>
        protected Item(ItemDefinition itemDefinition = null, uint id)
        {
            ID = id;
            m_ItemObjects = new ResizableArray<ItemObject>();
            m_ItemDefinition = itemDefinition;
            m_ItemDefinitionID = m_ItemDefinition?.ID ?? 0;
            m_Name = m_ItemDefinition?.name ?? "NULL";
        }
       
        /// <summary>
        /// This static functions creates an Item from an Item Definition.
        /// A list of attributes can be provided to override the default attribute values.
        /// </summary>
        /// <param name="itemDefinition">The Item Definition.</param>
        /// <param name="attributeOverrides">Any attribute that should override the default required attributes.</param>
        /// <returns>The created Item.</returns>
        public static Item Create(ItemDefinition itemDefinition, IReadOnlyList<AttributeBase> attributeOverrides = null, uint id)
        {
            if (itemDefinition == null) {
                Debug.LogWarning("Cannot create Item with null Item Definition.");
                return null;
            }

            var manager = itemDefinition.Manager;

            //If the category is immutable check if item alreadyExists in Inventory System Manager.
            if (itemDefinition.IsMutable == false && manager != null) {
                var registeredItem = manager.Register.ItemRegister.FindItemWithOverrides(itemDefinition, attributeOverrides);
                if (registeredItem != null) { return registeredItem; }
            }

            //Construct the new Item.
            var createdItem = new Item(itemDefinition, id);

            //Initialize does not register because register may need to replace this item by an existing equivalent one if the item is immutable.
            createdItem.Initialize(true);

            //Override any of the attributes.
            if (attributeOverrides != null) {
                createdItem.m_ItemAttributeCollection.OverrideAttributes((attributeOverrides, 0));
            }

            //Register (item can be replaced by an existing registered item).
            if (manager != null) {
                manager.Register.ItemRegister.Register(ref createdItem);
            }

            return createdItem;
        }

And then call the function Item.Create(itemDefinition, null, itemID) on the client.

Let me know how it goes. If that works (I haven't tried any network test yet so I'm not 100% sure it will, but it should) I can make a real/cleaner change for the next update 1.0.3. If not I'll try finding another solution.
 
Ya that worked. Thank you.

Follow up question:
Is it possible to get an item in the inventory by using the itemID as a search parameter?

Something like this:
inventory.GetItemByID(uint itemID) // returns item
 
Last edited:
I'm glad that work.
I'll make the change for version 1.0.3

When i'll make the change you'll probably need to refactor some of the code using
InventorySystemManager.CreateItem(item/itemdef, id)
instead of
Item.Create(item/itemdef,null,id)

The reason I make this abstraction is such that you can change the creation logic by swapping the manager by your own if you wanted to. That's for really advanced use cases where you may want to extend the Item, Item Definition, ItemCategory, etc... classes.

Is it possible to get an item in the inventory by using the itemID as a search parameter?

No that's not an option. instead you should do

C#:
var item = InventorySystemManager.GetItem(itemID);
var itemInfo = m_Inventory.GetItemInfo(item);

The inventory system manager will return the item for that ID. Some times that's enough to continue. But you may want to know the item amount, the item collection or the item stack where that item is stored in the inventory. You can get all this information from the item info.

Note GetItemInfo returns the info of the first item stack that matches the item, there could be more in the inventory. Depending on mutability and uniqueness that function could return an item with a different ID than the item you passed as parameter and that's normal.

If the item is Mutable and Unique, the ID must be the same.
If Immutable (whether it is unique or not), the ID must be the same too.
If it is Mutable and Common, the ID could be different. Mutable and Common items have flexible IDs that can change since they can merge with other similar item stacks.

I hope that makes sense
 
Last edited:
Top