Item, Icon, and Slot - meldavy/ipf-documentation GitHub Wiki

When you interact with items and skills, even buffs to some extent, you'll often times find yourself interacting with Icons.

Before we begin to map out the relationship, here are a few important table dumps:

ItemInfo

Below are various types of ItemInfo objects. These objects are retrieved and used in different contexts. Most commonly, INV_ITEM_INFO_C is used when manipulating items that are picked up and added to the inventory, or when an item is used from the inventory, etc. EQUIP_ITEM_INFO_C is used when examining equips of a PC, etc. While they slightly differ, their usage is almost always the same.

[EQUIP_ITEM_INFO_C]:  table {
    [__name]: string = EQUIP_ITEM_INFO_C
    [.get]:  table {
        [count]: function()
        [type]: function()
        [equipSpot]: function()
        [prop]: function()
        [isLockState]: function()
        [isChangeItem]: function()
        [object]: function()
    } // [.get]
    [GetObject]: function()
    [GetIESID]: function()
    [GetAdditionalModifiedString]: function()
    [GetEquipGemExp]: function()
    [GetEquipGemLv]: function()
    [IsAvailableSocket]: function()
    [ApplySocketOption]: function()
    [.set]:  table {
        [count]: function()
        [type]: function()
        [equipSpot]: function()
        [prop]: function()
        [isLockState]: function()
        [isChangeItem]: function()
        [object]: function()
    } // [.set]
    [GetEquipGemID]: function()
    [GetEquipGemRoastingLv]: function()
} // [EQUIP_ITEM_INFO_C]

[INV_ITEM_INFO_C]:  table {
    [__name]: string = INV_ITEM_INFO_C
    [GetAmountStr]: function()
    [.get]:  table {
        [invIndex]: function()
        [prop]: function()
        [price]: function()
        [object]: function()
        [isNew]: function()
        [type]: function()
        [hasLifeTime]: function()
        [fromWareHouse]: function()
        [count]: function()
        [isLockState]: function()
    } // [.get]
    [GetObject]: function()
    [GetIESID]: function()
    [GetAdditionalModifiedString]: function()
    [GetEquipGemExp]: function()
    [GetEquipGemLv]: function()
    [IsAvailableSocket]: function()
    [ApplySocketOption]: function()
    [.set]:  table {
        [invIndex]: function()
        [prop]: function()
        [price]: function()
        [object]: function()
        [isNew]: function()
        [type]: function()
        [hasLifeTime]: function()
        [fromWareHouse]: function()
        [count]: function()
        [isLockState]: function()
    } // [.set]
    [GetEquipGemID]: function()
    [GetEquipGemRoastingLv]: function()
} // [INV_ITEM_INFO_C]

[CABINET_ITEM_C]:  table {
    [__name]: string = CABINET_ITEM_C
    [.get]:  table {
        [itemType]: function()
        [sellItemAmount]: function()
    } // [.get]
    [GetObject]: function()
    [GetEquipGemLv]: function()
    [GetEquipGemExp]: function()
    [GetRegSysTime]: function()
    [.set]:  table {
        [itemType]: function()
        [sellItemAmount]: function()
    } // [.set]
    [IsAvailableSocket]: function()
    [GetCount]: function()
    [ApplySocketOption]: function()
    [GetItemID]: function()
    [GetEquipGemID]: function()
    [GetEquipGemRoastingLv]: function()
    [GetWhereFrom]: function()
} // [CABINET_ITEM_C]

The ItemInfo is a "description" and metadata regarding the item that is currently in context. For example when you pick up a new item from the ground, you can hook to multiple functions, or listen to different events where you interface with INV_ITEM_INFO_C type. The exposed getters for each type will give you most information that you need for local context (such as class ID, count, etc)

However, you might have the situation where you need more than just the basic context, such as equipment level, (ie: ark level), and that is when you need to get the IES Object.

local itemObj = GetIES(invItem:GetObject());

Note that GetObject() is always accompanied with GetIES(), and both are always used together. Thus, as good convention and standard, the usage should be done in a single line rather than separately:

-- recommended
local itemObj = GetIES(invItem:GetObject());

-- NOT recommended
local tempObj = invItem:GetObject();
localitemObj = GetIES(temptObj);

IES Object

IES Object is most commonly used with TryGetProp() to extract additional details of an item. Check this following first party source for usage examples.

This is where you will find information such as item level, experience, durability, etc.

Type Conversion from IES Object to ItemInfo

In the really rare case where you need to convert IES Object to ItemInfo, and we can assume that you want to convert it to INV_ITEM_INFO_C, we can do

local classID = obj.ClassID; -- or you can do TryGetProp(obj, "ClassID")
local iteminfo = session.GetInvItemByType(classID);

Type vs GUID/IESID

Type is synonymous to ClassID. Numeric ID. This means that the following are all equal and returns a numeric ID:

invItem.type
invItem.props.type
GetIES(invItem:GetObject()).ClassID

Similarly, ClassName is a non-numeric alphabetized ID.

GetIES(invItem:GetObject()).ClassName

This is useful for comparisons when checking if an item matches a certain type, but I personally prefer just using ClassID. Reason is because you cannot get ClassName from ItemInfo, but you can get ClassID from ItemInfo. So just using ClassID will help keep your code stay consistent.

GUID and IESID mean the same thing, and they are both IDs that refer to a specific unique "instance" of an item. For instance, let's say that you have two swords, both same type. But these two swords have different properties - different random option, different potential, different reinforcement, etc. These two swords have the same ClassName and ClassID but they have different GUID.

You can get GUID of an ItemInfo through:

invItem:GetIESID()

You can get Guid of IES Object through GetIESID():

GetIESID(item_obj)

Usually, when you are using GUID, you usually store it for later. (ie: When you drag an equip to a hotkey/slot, you save the GUID in an offline file, so that later when you load it, the slot is pointing to a specific instance of that item through the unique GUID)

You can convert a GUID back into an invItem through:

session.GetInvItemByGuid(guid)

Class

Often times you might run into the situation where you have an item type (ClassID) but you don't actually possess the item in your inventory. Thus, to get metadata of the item, you need to get the Class object:

local itemCls = GetClassByType("Item", classID)
local classID = itemCls.ClassID

This is also useful when you just want more information about an item, such as if it is an equipment or consumable.

It can also be used when you want to get the image of an item to set on a slot, even if you don't possess the item:

local img = itemCls.Icon;
SET_SLOT_IMG(slot, img);

Icon and IconInfo

When using an item from the inventory, or from your hotkey, or from any other slot, (which quite frankly is the only way to use skills and items), you will quite often interact with Icon and IconInfo. When you also interact with other windows such as the Awakening (itemdungeon) window, or when using Sandra for rerolling random options, first party code does not usually "keep track" of a reference to an item as a local variable, and instead relies on getting an ItemInfo from an Icon, which comes from a Slot.

local stoneIcon = stoneSlot:GetIcon();
local materialItemGuid = '0';
if stoneIcon ~= nil then
    materialItemGuid = stoneIcon:GetInfo():GetIESID();
end

As can be seen in the above example, icon:GetInfo() returns an IconInfo, which the table dump looks like this:

    [ICON_INFO]:  table {
        [__name]: string = ui::ICON_INFO
        [tolua_ubox]:  table {
        } // [tolua_ubox]
        [GetCategory]: function()
        [new]: function()
        [GetImageName]: function()
        [GetIESID]: function()
        [.set]:  table {
            [ext]: function()
            [type]: function()
            [count]: function()
        } // [.set]
        [.get]:  table {
            [ext]: function()
            [type]: function()
            [count]: function()
        } // [.get]
        [new_local]: function()
    } // [ICON_INFO]

info.type returns the classID of what was used (skill's classID, or item classID, etc), and info:GetIESID() returns the GUID.

info:GetCategory() returns the category, where examples can be found here.

Converting IconInfo to InvItemInfo

As mentioned above, iconInfo.type returns ClassID, and iconInfo.GetIESID() returns Guid. You can use the session.GetInvItem<>() functions to get an invItem, or you can also use GET_ICON_ITEM() declared in base.lua

Slots

Usually, when you use an item or a skill, you don't care much about the slot itself, you care more about the IconInfo. But when you want to set a slot's image to that of an item, or set the count text of a slot to the count of an item, you need to directly interact with the slot.

Let's say you drag an item to the slot and you want to modify the slot to reflect the item you dragged into it:

-- let's assume you got hold of a reference to invItemInfo with any mechanism
local invItemInfo = ...
local slot = frame:GetChild('my_slot');

-- now you want to set a slot to invItemInfo
imcSlot:SetItemInfo(slot, invItemInfo, invItemInfo.count);

There are various other ways to manipulate a slot, but ultimately the above function is called to "set" an item to a slot. And once an item is set on a slot, you can use the metadata from the slot's IconInfo and then convert it into an InvItem.