• 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!

C++ New Attributes Problem (Enum Limit?)

Derlexy

Intermediate OT User
Joined
Jun 29, 2011
Messages
219
Reaction score
101
Hello guys.

Im facing a problem that i have no clue about how to solve it. Ive created 2 new attributes for my server (TFS1.2), but when i ENUM them, only the 27 works, the 28 does not. Depending on what attribute i left on 27, it works and the other (left as 28) does not. I guess its some size limitation of the enum structure... How can i solve it?

C++:
enum itemAttrTypes : uint32_t {
    ITEM_ATTRIBUTE_NONE,

    ITEM_ATTRIBUTE_ACTIONID = 1 << 0,
    ITEM_ATTRIBUTE_MOVEMENTID = 1 << 1,
    ITEM_ATTRIBUTE_DESCRIPTION = 1 << 2,
    ITEM_ATTRIBUTE_TEXT = 1 << 3,
    ITEM_ATTRIBUTE_DATE = 1 << 4,
    ITEM_ATTRIBUTE_WRITER = 1 << 5,
    ITEM_ATTRIBUTE_NAME = 1 << 6,
    ITEM_ATTRIBUTE_ARTICLE = 1 << 7,
    ITEM_ATTRIBUTE_PLURALNAME = 1 << 8,
    ITEM_ATTRIBUTE_WEIGHT = 1 << 9,
    ITEM_ATTRIBUTE_ATTACK = 1 << 10,
    ITEM_ATTRIBUTE_DEFENSE = 1 << 11,
    ITEM_ATTRIBUTE_ARMOR = 1 << 12,
    ITEM_ATTRIBUTE_SHOOTRANGE = 1 << 13,
    ITEM_ATTRIBUTE_OWNER = 1 << 14,
    ITEM_ATTRIBUTE_DURATION = 1 << 15,
    ITEM_ATTRIBUTE_DECAYSTATE = 1 << 16,
    ITEM_ATTRIBUTE_CORPSEOWNER = 1 << 17,
    ITEM_ATTRIBUTE_CHARGES = 1 << 18,
    ITEM_ATTRIBUTE_FLUIDTYPE = 1 << 19,
    ITEM_ATTRIBUTE_DOORID = 1 << 20,
    ITEM_ATTRIBUTE_KEYNUMBER = 1 << 21,
    ITEM_ATTRIBUTE_KEYHOLENUMBER = 1 << 22,
    ITEM_ATTRIBUTE_DOORQUESTNUMBER = 1 << 23,
    ITEM_ATTRIBUTE_DOORQUESTVALUE = 1 << 24,
    ITEM_ATTRIBUTE_DOORLEVEL = 1 << 25,
    ITEM_ATTRIBUTE_CHESTQUESTNUMBER = 1 << 26,
    ITEM_ATTRIBUTE_ITEMCLASS = 1 << 27,
    ITEM_ATTRIBUTE_UPGRADES = 1 << 28,
};

The attributes im talking about are ITEM_ATTRIBUTE_ITEMCLASS and ITEM_ATTRIBUTE_UPGRADES.

Can someone help me?
 
What you mean with it doesnt work? Can you elaborate?


1 << 28 its on a valid range for uint32_t

Yeah. Well, when i use in game the method item:getAttribute(ITEM_ATTRIBUTE_ITEMCLASS) it returns me 0 or the value i set with item:setAttribute(ITEM_ATTRIBUTE_ITEMCLASS, value)... But when i do the same thing with ITEM_ATTRIBUTE_UPGRADES it returns me nil, even if i use the set method. Funny thing is that ive done them both EXACTLY the same way in server sources...
 
Try

enums.h
C++:
enum itemAttrTypes : uint32_t
{
    ITEM_ATTRIBUTE_NONE,
    ...
    ITEM_ATTRIBUTE_ITEMCLASS = 1 << 28,
    ITEM_ATTRIBUTE_UPGRADES = 1 << 29,
    ITEM_ATTRIBUTE_CUSTOM = 1U << 31
};

items.cpp
C++:
Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream)
{
    case ATTR_ITEMCLASS: {
        uint32_t itemClass;
        if (!propStream.read<uint32_t>(itemClass)) {
            return ATTR_READ_ERROR;
        }

        setIntAttr(ITEM_ATTRIBUTE_ITEMCLASS, itemClass);
        break;
    }

    case ATTR_UPGRADES: {
        uint32_t upgrades; // one value? try CUSTOM ATTRIBUTES
        if (!propStream.read<uint32_t>(upgrades)) {
            return ATTR_READ_ERROR;
        }

        setIntAttr(ITEM_ATTRIBUTE_UPGRADES, upgrades);
        break;
    }
}

C++:
void Item::serializeAttr(PropWriteStream& propWriteStream) const
{
     if (hasAttribute(ITEM_ATTRIBUTE_ITEMCLASS)) {
         propWriteStream.write<uint32_t>(ATTR_ITEMCLASS);
         propWriteStream.write<uint32_t>(getIntAttr(ITEM_ATTRIBUTE_ITEMCLASS));
     }

     if (hasAttribute(ITEM_ATTRIBUTE_UPGRADES)) {
         propWriteStream.write<uint32_t>(ATTR_UPGRADES);
         propWriteStream.write<uint32_t>(getIntAttr(ITEM_ATTRIBUTE_UPGRADES));
     }
}

items.h
Code:
const static uint32_t intAttributeTypes = +++ ITEM_ATTRIBUTE_ITEMCLASS | ITEM_ATTRIBUTE_UPGRADES;

C++:
enum AttrTypes_t
{
    // ATTR_DESCRIPTION = 1,
    ...
    ATTR_BOOST = 43,
    ATTR_ITEMCLASS = 44,
    ATTR_UPGRADES = 45,
};

luascript.cpp
Code:
registerEnum(ITEM_ATTRIBUTE_ITEMCLASS);
registerEnum(ITEM_ATTRIBUTE_UPGRADES);

ATTR_CUSTOM_ATTRIBUTES similar UPGRADES.
 
Try

enums.h
C++:
enum itemAttrTypes : uint32_t
{
    ITEM_ATTRIBUTE_NONE,
    ...
    ITEM_ATTRIBUTE_ITEMCLASS = 1 << 28,
    ITEM_ATTRIBUTE_UPGRADES = 1 << 29,
    ITEM_ATTRIBUTE_CUSTOM = 1U << 31
};

items.cpp
C++:
Attr_ReadValue Item::readAttr(AttrTypes_t attr, PropStream& propStream)
{
    case ATTR_ITEMCLASS: {
        uint32_t itemClass;
        if (!propStream.read<uint32_t>(itemClass)) {
            return ATTR_READ_ERROR;
        }

        setIntAttr(ITEM_ATTRIBUTE_ITEMCLASS, itemClass);
        break;
    }

    case ATTR_UPGRADES: {
        uint32_t upgrades; // one value? try CUSTOM ATTRIBUTES
        if (!propStream.read<uint32_t>(upgrades)) {
            return ATTR_READ_ERROR;
        }

        setIntAttr(ITEM_ATTRIBUTE_UPGRADES, upgrades);
        break;
    }
}

C++:
void Item::serializeAttr(PropWriteStream& propWriteStream) const
{
     if (hasAttribute(ITEM_ATTRIBUTE_ITEMCLASS)) {
         propWriteStream.write<uint32_t>(ATTR_ITEMCLASS);
         propWriteStream.write<uint32_t>(getIntAttr(ITEM_ATTRIBUTE_ITEMCLASS));
     }

     if (hasAttribute(ITEM_ATTRIBUTE_UPGRADES)) {
         propWriteStream.write<uint32_t>(ATTR_UPGRADES);
         propWriteStream.write<uint32_t>(getIntAttr(ITEM_ATTRIBUTE_UPGRADES));
     }
}

items.h
Code:
const static uint32_t intAttributeTypes = +++ ITEM_ATTRIBUTE_ITEMCLASS | ITEM_ATTRIBUTE_UPGRADES;

C++:
enum AttrTypes_t
{
    // ATTR_DESCRIPTION = 1,
    ...
    ATTR_BOOST = 43,
    ATTR_ITEMCLASS = 44,
    ATTR_UPGRADES = 45,
};

luascript.cpp
Code:
registerEnum(ITEM_ATTRIBUTE_ITEMCLASS);
registerEnum(ITEM_ATTRIBUTE_UPGRADES);

ATTR_CUSTOM_ATTRIBUTES similar UPGRADES.

Yeah, i've done all this on my sources, except this (because this is not a thing on my server distro):
items.h
Code:
const static uint32_t intAttributeTypes = +++ ITEM_ATTRIBUTE_ITEMCLASS | ITEM_ATTRIBUTE_UPGRADES;

Complementar information:

Server:
GitHub - Ezzz-dev/Nostalrius: Nostalrius is a 7.7 Tibia Clone Project based on The Forgotten Server 1.2 and CipSoft files. (https://github.com/Ezzz-dev/Nostalrius) (TFS 1.2 based)

About the attribute (UPGRADES): i can use it and show it on item description if i set it directly by my items declaration.
Example:
Code:
TypeID = 3286
Name = "a mace"
Flags = {MultiUse,Take,Weapon}
Attributes = {Weight=3800,WeaponType=CLUB,Attack=16,Defense=11,ItemClass=1,Upgrades=2}
The problem only happens when i try to manipulate the attribute by calling setAttribute and getAttribute methods on lua scripts (it always return me nil). Depending on what attribute i left on 27, it works and the other (left as 28) does not.
 
I don't use this disctro, but as far as I can remember TFS 1.2 or 1.3 when I started developing Trollheim I was struggling with same shit. So I think that you have to calculate new value for this number: 0xFFFFE13
C++:
        inline static bool isIntAttrType(itemAttrTypes type) {
            return (type & 0xFFFFE13) != 0;
        }
        inline static bool isStrAttrType(itemAttrTypes type) {
            return (type & 0x1EC) != 0;
        }

        const std::forward_list<Attribute>& getList() const {
            return attributes;
        }

If I remember corectly this number represents bit flag of every attribute there is in item. So for every attribute you set 1 if it is int or 0 if it is not. If you do this for every attribute you can then transform the number for Hex value like 0xFFFFE13
If you change value 0xFFFFE13 to bit it gives you 1111 1111 1111 1111 1110 0001 0011
Every 1 or 0 is the value of one attribute so:
you have to read from right to left:
ITEM_ATTRIBUTE_ACTIONID is 1 because it's int
ITEM_ATTRIBUTE_MOVEMENTID is 1 because it's int
ITEM_ATTRIBUTE_TEXT is 0- because it is not int
ITEM_ATTRIBUTE_DATE is 0 - same as above
So no there you have 0011 from the end of binary number
My guess is that you should add 0011 before "1111 1111 1111 1111 1110 0001 0011" and change to hex ti get 0x3FFFFE13
Let me now if anything from this helped you :)
 
I don't use this disctro, but as far as I can remember TFS 1.2 or 1.3 when I started developing Trollheim I was struggling with same shit. So I think that you have to calculate new value for this number: 0xFFFFE13
C++:
        inline static bool isIntAttrType(itemAttrTypes type) {
            return (type & 0xFFFFE13) != 0;
        }
        inline static bool isStrAttrType(itemAttrTypes type) {
            return (type & 0x1EC) != 0;
        }

        const std::forward_list<Attribute>& getList() const {
            return attributes;
        }

If I remember corectly this number represents bit flag of every attribute there is in item. So for every attribute you set 1 if it is int or 0 if it is not. If you do this for every attribute you can then transform the number for Hex value like 0xFFFFE13
If you change value 0xFFFFE13 to bit it gives you 1111 1111 1111 1111 1110 0001 0011
Every 1 or 0 is the value of one attribute so:
you have to read from right to left:
ITEM_ATTRIBUTE_ACTIONID is 1 because it's int
ITEM_ATTRIBUTE_MOVEMENTID is 1 because it's int
ITEM_ATTRIBUTE_TEXT is 0- because it is not int
ITEM_ATTRIBUTE_DATE is 0 - same as above
So no there you have 0011 from the end of binary number
My guess is that you should add 0011 before "1111 1111 1111 1111 1110 0001 0011" and change to hex ti get 0x3FFFFE13
Let me now if anything from this helped you :)

It worked!

Thank you very very much! Love ya. <3
 
Hello guys. I want someone to help me to edit item attribute to speed like: /attr speed, 30 change speed of boots of haste of +20 to +30.
Can someone help me?
 
Back
Top