• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Custom Attributes

pink_panther

Excellent OT User
Joined
Sep 10, 2016
Messages
1,171
Solutions
13
Reaction score
613
Location
Kazordoon
I was wondering if anyone can explain or provide more information about how the custom attributes work in TFS?

I found the PR here

I can see it seems to add some support for custom item attributes, but couldn't see how or anywhere it's used?

Thanks.
 
Lua:
local customAttribute = "CUSTOM_ITEM_LEVEL" --can be everything, its just an example
item:setCustomAttribute(customAttribute, 10)  -- now our item has custom attribute "CUSTOM_ITEM_LEVEL" with value 10.
item:getCustomAttribute(customAttribute) -- this will return our custom atttribute, in this case 10

--- some funcs as example

function Item.getLevel(self)
   local level = self:getCustomAttribute(customAttribute)
   if level then
      return level
   end
   return 0
end

function Item.setLevel(self, value)
    if not value then
       return nil
    end
    return self:setCustomAttribute(customAttribute, value)
end

-- item:setLevel(10)
-- item:getLevel()
Important: item:setCustomAttribute(attribute, value) work with strings aswell.
Lua:
-- item:setCustomAttribute("CITY_NAME", "thais")
 
Last edited:
Lua:
local customAttribute = "CUSTOM_ITEM_LEVEL" --can be everything, its just an example
item:setCustomAttribute(customAttribute, 10)  -- now our item has custom attribute "CUSTOM_ITEM_LEVEL" with value 10.
item:getCustomAttribute(customAttribute) -- this will return our custom atttribute, in this case 10

--- some funcs as example

function Item.getLevel(self)
   local level = self:getCustomAttribute(customAttribute)
   if level then
      return level
   end
   return 0
end

function Item.setLevel(self, value)
    if not value then
       return nil
    end
    return self:setCustomAttribute(customAttribute, value)
end

-- item:setLevel(10)
-- item:getLevel()
Important: item:setCustomAttribute(attribute, value) work with strings aswell.
Lua:
-- item:setCustomAttribute("CITY_NAME", "thais")
can we put life, mana leech and crit in an item with this function?

in nekiro 1.5 they call imbuements as SPECIAL, but idk if is possible to set an item with these imbuements or only via ITEMS.xml
 
Lua:
local customAttribute = "CUSTOM_ITEM_LEVEL" --can be everything, its just an example
item:setCustomAttribute(customAttribute, 10)  -- now our item has custom attribute "CUSTOM_ITEM_LEVEL" with value 10.
item:getCustomAttribute(customAttribute) -- this will return our custom atttribute, in this case 10

--- some funcs as example

function Item.getLevel(self)
   local level = self:getCustomAttribute(customAttribute)
   if level then
      return level
   end
   return 0
end

function Item.setLevel(self, value)
    if not value then
       return nil
    end
    return self:setCustomAttribute(customAttribute, value)
end

-- item:setLevel(10)
-- item:getLevel()
Important: item:setCustomAttribute(attribute, value) work with strings aswell.
Lua:
-- item:setCustomAttribute("CITY_NAME", "thais")

So you can just make up any "attribute" name as a string?

And this wouldn't actually do anything at all, unless this or another script calls/checks for this attribute for it to do something, right?

As an example I could take an existing regular item and give it a attribute like:
item:setCustomAttribute("QUEST_ITEM", 1) -- Asuming the item here is something otherwise useless or common like a wolf tooth necklace

Then later if a special door (a tile with a move action on it) requires a wolf tooth necklace to be worn to enter, it could check for this custom attribute so only this specific necklace could be used but not any regular looted necklace just put on to "cheat" the door without having to add a new custom item to the game for this 1 thing.

Is that the general idea?

can we put life, mana leech and crit in an item with this function?

in nekiro 1.5 they call imbuements as SPECIAL, but idk if is possible to set an item with these imbuements or only via ITEMS.xml
If my understanding is correct, you could then specify the leech or crit attribute be added to an item, however you would still need to edit combat function in sources to check for this custom attribute you've made up and have it apply a leech or crit chance based off the value that item has?

You'd also need to edit the get description (on look) to handle showing that the item has this specific attribute?

Am I understanding correctly?
 
So you can just make up any "attribute" name as a string?

And this wouldn't actually do anything at all, unless this or another script calls/checks for this attribute for it to do something, right?

As an example I could take an existing regular item and give it a attribute like:
item:setCustomAttribute("QUEST_ITEM", 1) -- Asuming the item here is something otherwise useless or common like a wolf tooth necklace

Then later if a special door (a tile with a move action on it) requires a wolf tooth necklace to be worn to enter, it could check for this custom attribute so only this specific necklace could be used but not any regular looted necklace just put on to "cheat" the door without having to add a new custom item to the game for this 1 thing.

Is that the general idea?


If my understanding is correct, you could then specify the leech or crit attribute be added to an item, however you would still need to edit combat function in sources to check for this custom attribute you've made up and have it apply a leech or crit chance based off the value that item has?

You'd also need to edit the get description (on look) to handle showing that the item has this specific attribute?

Am I understanding correctly?
Yeah, mostly of this things are only visual if you dont handle it inside (refer to leech and crit).
 
Yeah, mostly of this things are only visual if you dont handle it inside (refer to leech and crit).
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if target.itemid == 2398 then -- mace
    target:setAttribute("manaleechchance", 10)
--    target:setCustomAttribute("manaleechchance", 15)
    end
    return true
end

tried setAttribute and Custom, but doesnt work or maybe idk how to make work.

when I go to items.xml and put the key, it works normally, but if I try to give this attribute to a specific weapon using these functions, nothing happens, know why or where im wrong
 
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if target.itemid == 2398 then -- mace
    target:setAttribute("manaleechchance", 10)
--    target:setCustomAttribute("manaleechchance", 15)
    end
    return true
end

tried setAttribute and Custom, but doesnt work or maybe idk how to make work.

when I go to items.xml and put the key, it works normally, but if I try to give this attribute to a specific weapon using these functions, nothing happens, know why or where im wrong
Well this will set the attribute, but you still need to edit your source files to actually check for and roll the mana leech attrib
 
Well this will set the attribute, but you still need to edit your source files to actually check for and roll the mana leech attrib
the source already has something related to imbuements(nekiro 1.5), I just don't know if it's possible to do it this way or just via items.xml.

when i edit items.xml work well but I would like to be able to assign (similar to imbuements) to a specific item an attribute and % specifies
 

Attachments

So you can just make up any "attribute" name as a string?

And this wouldn't actually do anything at all, unless this or another script calls/checks for this attribute for it to do something, right?

As an example I could take an existing regular item and give it a attribute like:
item:setCustomAttribute("QUEST_ITEM", 1) -- Asuming the item here is something otherwise useless or common like a wolf tooth necklace

Then later if a special door (a tile with a move action on it) requires a wolf tooth necklace to be worn to enter, it could check for this custom attribute so only this specific necklace could be used but not any regular looted necklace just put on to "cheat" the door without having to add a new custom item to the game for this 1 thing.

Is that the general idea?


If my understanding is correct, you could then specify the leech or crit attribute be added to an item, however you would still need to edit combat function in sources to check for this custom attribute you've made up and have it apply a leech or crit chance based off the value that item has?

You'd also need to edit the get description (on look) to handle showing that the item has this specific attribute?

Am I understanding correctly?
Exatcly, you must add to source or create new scripts / funcs to make it usefull, its just only store the values.
 
the source already has something related to imbuements(nekiro 1.5), I just don't know if it's possible to do it this way or just via items.xml.

when i edit items.xml work well but I would like to be able to assign (similar to imbuements) to a specific item an attribute and % specifies
Its possible and actually pretty simple, there is 2 ways:

1 - using customAttributes and internal item description to properly update the item name (lib/core/item.lua), then read custom attribute to make a condition

2 - saving the attribute on the item description and then read it to make a condition

Both ways can be triggered by a movement or onInventoryUpdate
 
So if i want make something like stone attack speed upgrade something like this

Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isItem() then
        return false
    end
    local position = (toPosition.x ~= 65535 and toPosition or player:getPostion())
    target:getAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED, math.random(100, 200))
    target:setAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED, math.random(100, 200))
    target:setCustomAttribute('Attack speed', math.random(100, 200))
    target:getCustomAttribute('Attack speed')
    position:sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)
    return true
end
How to register this to item? I know it works with items.xml because i register it on item.lua and it works perfectly.
 
Its possible and actually pretty simple, there is 2 ways:

1 - using customAttributes and internal item description to properly update the item name (lib/core/item.lua), then read custom attribute to make a condition

2 - saving the attribute on the item description and then read it to make a condition

Both ways can be triggered by a movement or onInventoryUpdate
Well I was looking to make a custom attribute by editing the item description attribute, but just using an actual custom attribute would be less messy and easier to get/set
 
So if i want make something like stone attack speed upgrade something like this

For attack speed there is no need to use customAttributes, item name description will be updated automatically
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isItem() then
        return false
    end

    local speed = math.random(500, 1000) -- its in miliseconds
    target:setAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED, speed)
 
    target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)

    return true
end

Well I was looking to make a custom attribute by editing the item description attribute, but just using an actual custom attribute would be less messy and easier to get/set
It would say more cleaner, since you can merge a custom attribute with default attributes (f.e skill + skill) on items name using internal item desc
 
Last edited:
For attack speed there is no need to use customAttributes, item name description will be updated automatically

Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isItem() then
        return false
    end

    local speed = math.random(500, 1000) -- its in miliseconds
    target:setAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED, speed)
   
    target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)

    return true
end
Well the problem is that it's not displaying, but when i put it in items.xml it's displaying xD
But after i use the script it does change the value but not the display i don't know why :p
I'm using luaitemdesc so i put it like this in item.lua

Lua:
        if it:getAttackSpeed() ~= 0 then
            begin = addSeparator(ss, begin)
            ss:append('Attack speed %s%d', showpos(it:getAttackSpeed()), math.abs(it:getAttackSpeed() / 2))
            end
n2AMlMD.png
 
For attack speed there is no need to use customAttributes, item name description will be updated automatically
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if not target:isItem() then
        return false
    end

    local speed = math.random(500, 1000) -- its in miliseconds
    target:setAttribute(ITEM_ATTRIBUTE_ATTACK_SPEED, speed)
 
    target:getPosition():sendMagicEffect(CONST_ME_MAGIC_RED)
    item:remove(1)

    return true
end


It would say more cleaner, since you can merge a custom attribute with default attributes (f.e skill + skill) on items name using internal item desc
Yeah, I'm using TFS 1.2, I've just pulled this PR so will give it a test.

I know I'll still need to update Item::getDescription() in item.cpp
Well the problem is that it's not displaying, but when i put it in items.xml it's displaying xD
But after i use the script it does change the value but not the display i don't know why :p
I'm using luaitemdesc so i put it like this in item.lua

Lua:
        if it:getAttackSpeed() ~= 0 then
            begin = addSeparator(ss, begin)
            ss:append('Attack speed %s%d', showpos(it:getAttackSpeed()), math.abs(it:getAttackSpeed() / 2))
            end
n2AMlMD.png

Check Item::getDescription in sources for items.cpp

While I was testing changing item attack and defence on weapons, the attack would increase but it still said the default attack value when looking at the item.

If you see in Item::getDescription it returns the itemtype default value, not the current items value, like this

Example, it's normally this
C++:
            if (it.attack != 0) {
                s << "Atk:" << static_cast<int>(it.attack);
            }

Which I changed to something like this instead
C++:
            if (item && item->getAttack() > it.attack) {
                s << "Atk:" << static_cast<int>(it.attack);
            } else if (it.attack != 0) {
                s << "Atk:" << static_cast<int>(it.attack);
            }

You may need to do something similar for this and/or other attributes

But like I said, im using 1.2 so some of the lua onlook description doesnt exist for me.
 
Now i checked when i have
Lua:
luaItemDesc = false
it does work and update it normally so the problem is in lib/core/item.lua then.
But what is wrong here xD
Lua:
        if it:getAttackSpeed() ~= 0 then
            begin = addSeparator(ss, begin)
            ss:append('Attack speed %s%d', showpos(it:getAttackSpeed()), math.abs(it:getAttackSpeed() / 2))
            end



in item.cpp i have it register like this
C++:
            uint32_t attackSpeed = item ? item->getAttackSpeed() : it.attackSpeed;
            if (attackSpeed) {
                if (begin) {
                    begin = false;
                    s << " (";
                } else {
                    s << ", ";
                }

                s << "Atk Spd:" << (attackSpeed / 1000.) << "s";
            }
 
With using source files it does update the attribute and changing the value in description like this
rCErUMO.png


But with using luaitemdescription it goes like this xD don't changing anything at all


OUoHUXX.png
 
It's cool maybe i figure it out someday :D
Anyway im highly interested also how to make that custom attributes :p
 
Back
Top