Derlexy
Well-Known Member
- Joined
- Jun 29, 2011
- Messages
- 218
- Reaction score
- 99
Hello guys, how are you? I hope youre all okay.
Quick Resume: I have a upgrade system on my server that players can upgrade items from +1 to +9. Each upgrade gives the item a attribute bonus based on item attributes pool. This system is fully working on server side! Ive implemented it by creating new item attributes. What Im trying to do is to read this attribute values on client side and set a colored frame on items that have been upgraded.
First things first:
How I have implemented it:
I'll not show every piece of code, it would be too long, but you can assume that its working, all the functions on server side works like every original attributes. If you want to know something i've omited, feel free to ask.
Server side: item.h
Server side: item.cpp at "void Item::serializeAttr(PropWriteStream& propWriteStream) const":
As I said, the server side stuff is working, items are correctly being saved on database, all the attributes effects are being applied and are working in game.
What I have on my OTCv8:
To be abble to debug if the attributes that are being serialized (on server side) are being read on client side, i have implemented this tooltip: Item stats on Hover-Mouse (https://otland.net/threads/item-stats-on-hover-mouse.272007/#post-2619950)
The tooltop is working, like you can see here:
Client side: item.h:
As you can se here, on server side the attrbiute ATTR_UPGRADES = 39 and on client side this attribute is ATTR_HITCHANCE = 39. I believe the name doesnt matter, its just a enumeration, but, 39 is what we want, right?
Client side: item.cpp at "void Item::unserializeItem(const BinaryTreePtr &in)":
As we can see here, the attribute 39 (on client side its enumerated as ATTR_HITCHANCE) is being read and saved on m_attribs, right?
So, to be able to get this attribute value, i tried to do this:
On item.cpp i changed this:
To this:
But, as we can see, the result i have is as follows:
It should show "Item Count: 7" if this attribute reading was working... But why 7? Because this blue robe is upgraded to +7, and the attribute that holds this 7 number is the ATTR_UPGRADES on server side, the attribute enumerated as 39:
Where the hell the description gets this +7 alongside the item name? From here: server side at item.cpp on "std::string Item::getDescription(lot of parameters)":
This getUpgrades() functions gets the value stored at item attribute 39.
Can someonse please help me to understand that?
Quick Resume: I have a upgrade system on my server that players can upgrade items from +1 to +9. Each upgrade gives the item a attribute bonus based on item attributes pool. This system is fully working on server side! Ive implemented it by creating new item attributes. What Im trying to do is to read this attribute values on client side and set a colored frame on items that have been upgraded.
First things first:
- Server Distribution: 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)
- Client: GitHub - OTCv8/otcv8-dev: OTCv8 Development repository (source code) (https://github.com/OTCv8/otcv8-dev)
How I have implemented it:
I'll not show every piece of code, it would be too long, but you can assume that its working, all the functions on server side works like every original attributes. If you want to know something i've omited, feel free to ask.
Server side: item.h
C++:
enum AttrTypes_t {
//ATTR_DESCRIPTION = 1,
//ATTR_EXT_FILE = 2,
ATTR_TILE_FLAGS = 3,
ATTR_ACTION_ID = 4,
ATTR_MOVEMENT_ID = 5,
ATTR_TEXT = 6,
ATTR_DESC = 7,
ATTR_TELE_DEST = 8,
ATTR_ITEM = 9,
ATTR_DEPOT_ID = 10,
//ATTR_EXT_SPAWN_FILE = 11,
ATTR_RUNE_CHARGES = 12,
//ATTR_EXT_HOUSE_FILE = 13,
ATTR_HOUSEDOORID = 14,
ATTR_COUNT = 15,
ATTR_DURATION = 16,
ATTR_DECAYING_STATE = 17,
ATTR_WRITTENDATE = 18,
ATTR_WRITTENBY = 19,
ATTR_SLEEPERGUID = 20,
ATTR_SLEEPSTART = 21,
ATTR_CHARGES = 22,
ATTR_KEYNUMBER = 23,
ATTR_KEYHOLENUMBER = 24,
ATTR_DOORQUESTNUMBER = 25,
ATTR_DOORQUESTVALUE = 26,
ATTR_DOORLEVEL = 27,
ATTR_CHESTQUESTNUMBER = 28,
// add non-OTBM attributes after here
ATTR_CONTAINER_ITEMS = 29,
ATTR_NAME = 30,
ATTR_ARTICLE = 31,
ATTR_PLURALNAME = 32,
ATTR_WEIGHT = 33,
ATTR_ATTACK = 34,
ATTR_DEFENSE = 35,
ATTR_ARMOR = 36,
ATTR_SHOOTRANGE = 37,
ATTR_ITEMCLASS = 38,
ATTR_UPGRADES = 39,
ATTR_UPG_ATTACK = 40,
ATTR_UPG_DEFENSE = 41,
ATTR_UPG_ARMOR = 42,
ATTR_UPG_SPEED = 43,
ATTR_UPG_LEAN = 44,
ATTR_UPG_CAPACITY = 45,
ATTR_UPG_RANGE = 46,
ATTR_UPG_HEALTH = 47,
ATTR_UPG_MANA = 48,
ATTR_UPG_MAGIC = 49,
ATTR_UPG_SWORD = 50,
ATTR_UPG_AXE = 51,
ATTR_UPG_CLUB = 52,
ATTR_UPG_SHIELD = 53,
ATTR_UPG_DISTANCE = 54,
};
Server side: item.cpp at "void Item::serializeAttr(PropWriteStream& propWriteStream) const":
C++:
if (hasAttribute(ITEM_ATTRIBUTE_UPGRADES)) {
propWriteStream.write<uint8_t>(ATTR_UPGRADES);
propWriteStream.write<int32_t>(getIntAttr(ITEM_ATTRIBUTE_UPGRADES));
}
As I said, the server side stuff is working, items are correctly being saved on database, all the attributes effects are being applied and are working in game.
What I have on my OTCv8:
To be abble to debug if the attributes that are being serialized (on server side) are being read on client side, i have implemented this tooltip: Item stats on Hover-Mouse (https://otland.net/threads/item-stats-on-hover-mouse.272007/#post-2619950)
Lua:
function UIItem:onHoverChange(hovered)
UIWidget.onHoverChange(self, hovered)
local item = self:getItem()
if item and not self:getTooltip() then
self:setTooltip('Item Count: ' .. item:getCount())
end
if self:isVirtual() or not self:isDraggable() then return end
local draggingWidget = g_ui.getDraggingWidget()
if draggingWidget and self ~= draggingWidget then
local gotMap = draggingWidget:getClassName() == 'UIGameMap'
local gotItem = draggingWidget:getClassName() == 'UIItem' and not draggingWidget:isVirtual()
if hovered and (gotItem or gotMap) then
self:setBorderWidth(1)
draggingWidget.hoveredWho = self
else
self:setBorderWidth(0)
draggingWidget.hoveredWho = nil
end
end
end


Client side: item.h:
As you can se here, on server side the attrbiute ATTR_UPGRADES = 39 and on client side this attribute is ATTR_HITCHANCE = 39. I believe the name doesnt matter, its just a enumeration, but, 39 is what we want, right?
C++:
enum ItemAttr : uint8
{
ATTR_END = 0,
//ATTR_DESCRIPTION = 1,
//ATTR_EXT_FILE = 2,
ATTR_TILE_FLAGS = 3,
ATTR_ACTION_ID = 4,
ATTR_UNIQUE_ID = 5,
ATTR_TEXT = 6,
ATTR_DESC = 7,
ATTR_TELE_DEST = 8,
ATTR_ITEM = 9,
ATTR_DEPOT_ID = 10,
//ATTR_EXT_SPAWN_FILE = 11,
ATTR_RUNE_CHARGES = 12,
//ATTR_EXT_HOUSE_FILE = 13,
ATTR_HOUSEDOORID = 14,
ATTR_COUNT = 15,
ATTR_DURATION = 16,
ATTR_DECAYING_STATE = 17,
ATTR_WRITTENDATE = 18,
ATTR_WRITTENBY = 19,
ATTR_SLEEPERGUID = 20,
ATTR_SLEEPSTART = 21,
ATTR_CHARGES = 22,
ATTR_CONTAINER_ITEMS = 23,
ATTR_NAME = 30,
ATTR_PLURALNAME = 31,
ATTR_ATTACK = 33,
ATTR_EXTRAATTACK = 34,
ATTR_DEFENSE = 35,
ATTR_EXTRADEFENSE = 36,
ATTR_ARMOR = 37,
ATTR_ATTACKSPEED = 38,
ATTR_HITCHANCE = 39,
ATTR_SHOOTRANGE = 40,
ATTR_ARTICLE = 41,
ATTR_SCRIPTPROTECTED = 42,
ATTR_DUALWIELD = 43,
ATTR_ATTRIBUTE_MAP = 128
};
Client side: item.cpp at "void Item::unserializeItem(const BinaryTreePtr &in)":
As we can see here, the attribute 39 (on client side its enumerated as ATTR_HITCHANCE) is being read and saved on m_attribs, right?
C++:
void Item::unserializeItem(const BinaryTreePtr &in)
{
try {
while(in->canRead()) {
int attrib = in->getU8();
if(attrib == 0)
break;
switch(attrib) {
case ATTR_COUNT:
case ATTR_RUNE_CHARGES:
setCount(in->getU8());
break;
case ATTR_CHARGES:
setCount(in->getU16());
break;
case ATTR_HOUSEDOORID:
case ATTR_SCRIPTPROTECTED:
case ATTR_DUALWIELD:
case ATTR_DECAYING_STATE:
m_attribs.set(attrib, in->getU8());
break;
case ATTR_ACTION_ID:
case ATTR_UNIQUE_ID:
case ATTR_DEPOT_ID:
m_attribs.set(attrib, in->getU16());
break;
case ATTR_CONTAINER_ITEMS:
case ATTR_ATTACK:
case ATTR_EXTRAATTACK:
case ATTR_DEFENSE:
case ATTR_EXTRADEFENSE:
case ATTR_ARMOR:
case ATTR_ATTACKSPEED:
case ATTR_HITCHANCE:
case ATTR_DURATION:
case ATTR_WRITTENDATE:
case ATTR_SLEEPERGUID:
case ATTR_SLEEPSTART:
case ATTR_ATTRIBUTE_MAP:
m_attribs.set(attrib, in->getU32());
break;
case ATTR_TELE_DEST: {
Position pos;
pos.x = in->getU16();
pos.y = in->getU16();
pos.z = in->getU8();
m_attribs.set(attrib, pos);
break;
}
case ATTR_NAME:
case ATTR_TEXT:
case ATTR_DESC:
case ATTR_ARTICLE:
case ATTR_WRITTENBY:
m_attribs.set(attrib, in->getString());
break;
default:
stdext::throw_exception(stdext::format("invalid item attribute %d", attrib));
}
}
} catch(stdext::exception& e) {
g_logger.error(stdext::format("Failed to unserialize OTBM item: %s", e.what()));
}
}
So, to be able to get this attribute value, i tried to do this:
On item.cpp i changed this:
C++:
int Item::getCount()
{
if(isStackable())
return m_countOrSubType;
return 1;
}
To this:
C++:
int Item::getCount()
{
return m_attribs.get<uint32>(ATTR_HITCHANCE);
// if(isStackable())
// return m_countOrSubType;
// return 1;
}
But, as we can see, the result i have is as follows:

It should show "Item Count: 7" if this attribute reading was working... But why 7? Because this blue robe is upgraded to +7, and the attribute that holds this 7 number is the ATTR_UPGRADES on server side, the attribute enumerated as 39:

Where the hell the description gets this +7 alongside the item name? From here: server side at item.cpp on "std::string Item::getDescription(lot of parameters)":
C++:
std::string Item::getDescription(const ItemType& it, int32_t lookDistance,
const Item* item /*= nullptr*/, int32_t subType /*= -1*/, bool addArticle /*= true*/)
{
// some code before
if (item->getUpgrades() > 0) {
s << " +" << item->getUpgrades();
}
// lot of code after
}
Can someonse please help me to understand that?