Merge with feature-item-icon-buffs

--HG--
branch : yubo
hg/yubo
Nimetu 6 years ago
commit a22767af76

@ -4493,6 +4493,13 @@ NLMISC_COMMAND(debugItemInfoWaiters, "log ItemInfoWaiters", "")
return true;
}
NLMISC_COMMAND(debugItemInfoCache, "log ItemInfoCache", "")
{
getInventory().debugItemInfoCache();
return true;
}
NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "")
{
CInterfaceHelp::debugOpenedInfoWindows();

@ -75,52 +75,52 @@ const uint64 NOTIFY_ANIM_MS_DURATION = 1000;
// ***************************************************************************
// **********************************************************************************************************
class CControlSheetTooltipInfoWaiter : public IItemInfoWaiter
void CControlSheetInfoWaiter::sendRequest()
{
public:
// The item used to open this window
CDBCtrlSheet* CtrlSheet;
string LuaMethodName;
public:
ucstring infoValidated(CDBCtrlSheet* ctrlSheet, string luaMethodName);
virtual void infoReceived();
};
static CControlSheetTooltipInfoWaiter ControlSheetTooltipUpdater;
Requesting = true;
getInventory().addItemInfoWaiter(this);
}
void CControlSheetTooltipInfoWaiter::infoReceived()
void CControlSheetInfoWaiter::infoReceived()
{
getInventory().removeItemInfoWaiter(&ControlSheetTooltipUpdater);
infoValidated(CtrlSheet, LuaMethodName);
if (!Requesting) {
return;
}
getInventory().removeItemInfoWaiter(this);
infoValidated();
CtrlSheet->infoReceived();
Requesting = false;
}
ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet, string luaMethodName)
ucstring CControlSheetInfoWaiter::infoValidated() const
{
ucstring help;
// delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= CLuaManager::getInstance().getLuaState();
if (CtrlSheet && !LuaMethodName.empty())
{
CLuaStackRestorer lsr(ls, 0);
// delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= CLuaManager::getInstance().getLuaState();
{
CLuaStackRestorer lsr(ls, 0);
CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)ctrlSheet);
ls->pushGlobalTable();
CLuaObject game(*ls);
game = game["game"];
game.callMethodByNameNoThrow(luaMethodName.c_str(), 1, 1);
CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)CtrlSheet);
ls->pushGlobalTable();
CLuaObject game(*ls);
game = game["game"];
game.callMethodByNameNoThrow(LuaMethodName.c_str(), 1, 1);
// retrieve result from stack
if (!ls->empty())
{
CLuaIHM::pop(*ls, help);
}
else
{
nlwarning(toString("Ucstring result expected when calling '%s', possible script error", luaMethodName.c_str()).c_str());
// retrieve result from stack
if (!ls->empty())
{
CLuaIHM::pop(*ls, help);
}
else
{
nlwarning(toString("Ucstring result expected when calling '%s', possible script error", LuaMethodName.c_str()).c_str());
}
}
}
@ -137,7 +137,7 @@ int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls)
// ***************************************************************************
int CDBCtrlSheet::luaGetItemInfo(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet *>(this);
uint32 itemSlotId = getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
@ -237,7 +237,6 @@ int CDBCtrlSheet::luaWaitInfo(CLuaState &ls)
int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
@ -505,6 +504,7 @@ CCtrlDraggable(param)
_Useable= true;
_GrayedLink= NULL;
_NeedSetup= true;
_ItemInfoChanged = true;
_IconW = 0;
_IconH = 0;
_SetupInit= false;
@ -528,6 +528,11 @@ CCtrlDraggable(param)
_ItemRMClassType= NULL;
_ItemRMFaberStatType= NULL;
_NotifyAnimEndTime = 0;
_HpBuffIcon = "ico_heal.tga";
_SapBuffIcon = "ico_sap.tga";
_StaBuffIcon = "ico_stamina.tga";
_FocusBuffIcon = "ico_focus.tga";
}
// ----------------------------------------------------------------------------
@ -535,6 +540,11 @@ CDBCtrlSheet::~CDBCtrlSheet()
{
NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
if (_ItemInfoWaiter.Requesting)
{
getInventory().removeItemInfoWaiter(&_ItemInfoWaiter);
}
if (_GuildBack)
{
if (Driver)
@ -613,6 +623,22 @@ bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
prop = (char*) xmlGetProp( cur, (xmlChar*)"slot" );
if(prop) _DrawSlot= CInterfaceElement::convertBool(prop);
//
_HpBuffIcon = "ico_heal.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"hp_buff_icon" );
if (prop) _HpBuffIcon = string((const char *)prop);
_SapBuffIcon = "ico_sap.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"sap_buff_icon" );
if (prop) _SapBuffIcon = string((const char *)prop);
_StaBuffIcon = "ico_stamina.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"sta_buff_icon" );
if (prop) _StaBuffIcon = string((const char *)prop);
_FocusBuffIcon = "ico_focus.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
if (prop) _FocusBuffIcon = string((const char *)prop);
updateActualType();
// Init size for Type
@ -1040,6 +1066,64 @@ void CDBCtrlSheet::updateIconSize()
}
}
// ***************************************************************************
void CDBCtrlSheet::infoReceived()
{
if (!_ItemSheet)
{
return;
}
const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
if (itemInfo == NULL)
{
// schedule for recheck on next draw()
_ItemInfoChanged = true;
return;
}
// crystallized spell
{
_EnchantIcons.clear();
CViewRenderer &rVR = *CViewRenderer::getInstance();
CSBrickManager *pBM= CSBrickManager::getInstance();
for(uint i=0; i<itemInfo->Enchantment.Bricks.size(); ++i)
{
const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
if (brick)
{
if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
{
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
else if (brick->isRoot())
{
// there should be single root icon and it should be first one
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
}
}
}
// buff icons
{
_BuffIcons.clear();
CViewRenderer &rVR = *CViewRenderer::getInstance();
if (itemInfo->HpBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_HpBuffIcon)));
if (itemInfo->SapBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_SapBuffIcon)));
if (itemInfo->StaBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_StaBuffIcon)));
if (itemInfo->FocusBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_FocusBuffIcon)));
// update sizes
for(uint i = 0; i < _BuffIcons.size(); ++i)
{
rVR.getTextureSizeFromId(_BuffIcons[i].TextureId, _BuffIcons[i].IconW, _BuffIcons[i].IconH);
}
}
}
// ***************************************************************************
void CDBCtrlSheet::setupPact()
@ -1103,6 +1187,7 @@ void CDBCtrlSheet::setupItem ()
CInterfaceManager *pIM= CInterfaceManager::getInstance();
sint32 sheet = _SheetId.getSInt32();
// If this is the same sheet, need to resetup
if (_LastSheetId != sheet || _NeedSetup)
{
@ -1203,6 +1288,9 @@ void CDBCtrlSheet::setupItem ()
// Special Item requirement
updateItemCharacRequirement(_LastSheetId);
// update item info markers
_ItemInfoChanged = true;
}
else
{
@ -1277,6 +1365,13 @@ void CDBCtrlSheet::setupItem ()
_Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
}
*/
// at each frame, update item info icon if changed
if (_ItemInfoChanged)
{
_ItemInfoChanged = false;
setupItemInfoWaiter();
}
}
@ -2220,6 +2315,69 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
}
if (!_BuffIcons.empty())
{
// there is max 4 icons
sint32 hArea = (hSheet / 4);
sint32 xIcon = x;
sint32 yIcon = y;
for (uint i = 0; i < _BuffIcons.size(); ++i)
{
sint32 wIcon = _BuffIcons[i].IconW;
sint32 hIcon = _BuffIcons[i].IconH;
if (hIcon > hArea)
{
wIcon = wIcon * ((float)hArea / hIcon);
hIcon = hArea;
}
rVR.drawRotFlipBitmap (_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _BuffIcons[i].TextureId, fastMulRGB(curSheetColor, _BuffIcons[i].Color));
xIcon += wIcon;
// move up the row for 3rd/4th icon
if (i % 3 == 1) {
xIcon = x;
yIcon += hIcon;
}
}
}
// Is the item enchanted ?
sint32 enchant = _Enchant.getSInt32();
if (enchant > 0)
{
// Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
enchant--;
rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
}
if (!_EnchantIcons.empty())
{
// should only only 2 icons at most
// draw them in single line, top-right
sint32 hArea = (hSheet / 3);
sint32 xIcon = x + wSheet - 1;
sint32 yIcon = y + hSheet - 1/* - hArea*/;
// 0 is expected to be background
for (uint i = 1; i < _EnchantIcons.size(); ++i)
{
sint32 wIcon = _EnchantIcons[i].IconW;
sint32 hIcon = _EnchantIcons[i].IconH;
if (hIcon > hArea)
{
wIcon = wIcon * ((float)hArea / hIcon);
hIcon = hArea;
}
// need to move x before draw because of right aligned
if (i == 1)
{
xIcon -= wIcon;
}
yIcon -= hIcon;
rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
rVR.drawRotFlipBitmap(_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
}
}
// Draw Quality. -1 for lookandfeel. Draw it with global color
if (_DispQuality != -1)
{
@ -2242,15 +2400,6 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
}
drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false);
}
// Is the item enchanted ?
sint32 enchant = _Enchant.getSInt32();
if (enchant > 0)
{
// Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
enchant--;
rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
}
// if a raw material for example, must add special icon text.
displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
@ -3114,6 +3263,53 @@ const COutpostBuildingSheet *CDBCtrlSheet::asOutpostBuildingSheet() const
return NULL;
}
// ***************************************************************************
void CDBCtrlSheet::setupItemInfoWaiter()
{
const CItemSheet *item = asItemSheet();
if(!item)
return;
if (!useItemInfoForFamily(item->Family))
return;
if (getItemSerial() == 0 || getItemCreateTime() == 0)
return;
string luaMethodName = ((item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip");
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint itemSlotId = getInventory().getItemSlotId(ctrlSheet);
// Prepare the waiter for tooltips
_ItemInfoWaiter.ItemSheet= ctrlSheet->getSheetId();
_ItemInfoWaiter.LuaMethodName = luaMethodName;
_ItemInfoWaiter.ItemSlotId= itemSlotId;
_ItemInfoWaiter.CtrlSheet = ctrlSheet;
// send out request only if cache is not set
const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
if (itemInfo)
{
infoReceived();
}
else
{
// Using isInventoryPresent/Available() will fail for packers when out of range
// Getting server item however will work correctly for packer/room/guild
const CItemImage *itemImage = getInventory().getServerItem(itemSlotId);
if (itemImage)
{
_ItemInfoWaiter.sendRequest();
}
else
{
// schedule for next draw() - if inventory should not be available (ie guild),
// but user opens it anyway, then this will loop back here on every draw()
_ItemInfoChanged = true;
}
}
}
// ***************************************************************************
void CDBCtrlSheet::getContextHelp(ucstring &help) const
{
@ -3177,34 +3373,17 @@ void CDBCtrlSheet::getContextHelp(ucstring &help) const
{
if (useItemInfoForFamily(item->Family))
{
string luaMethodName = ( (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip");
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
CCtrlBase *ctrlBase = const_cast<CDBCtrlSheet*>(this);
if ( ! getInventory().isItemInfoUpToDate(getInventory().getItemSlotId(ctrlSheet)))
{
// Prepare the waiter
ControlSheetTooltipUpdater.ItemSheet= ctrlSheet->getSheetId();
ControlSheetTooltipUpdater.LuaMethodName = luaMethodName;
ControlSheetTooltipUpdater.ItemSlotId= getInventory().getItemSlotId(ctrlSheet);
ControlSheetTooltipUpdater.CtrlSheet = ctrlSheet;
// Add the waiter
getInventory().addItemInfoWaiter(&ControlSheetTooltipUpdater);
}
if (!_ContextHelp.empty())
{
help= _ContextHelp;
ctrlBase->setDefaultContextHelp(ucstring());
}
else
help = ControlSheetTooltipUpdater.infoValidated(ctrlSheet, luaMethodName);
// call lua function to update tooltip window
help = _ItemInfoWaiter.infoValidated();
}
else if (!_ContextHelp.empty())
{
help = _ContextHelp;
}
else
if (!_ContextHelp.empty())
help= _ContextHelp;
else
help= getItemActualName();
{
help = getItemActualName();
}
}
else
help= _ContextHelp;
@ -3322,21 +3501,7 @@ void CDBCtrlSheet::getContextHelpToolTip(ucstring &help) const
{
if (useItemInfoForFamily(item->Family))
{
string luaMethodName = (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip";
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
if ( ! getInventory().isItemInfoUpToDate(getInventory().getItemSlotId(ctrlSheet)))
{
// Prepare the waiter
ControlSheetTooltipUpdater.ItemSheet= ctrlSheet->getSheetId();
ControlSheetTooltipUpdater.LuaMethodName = luaMethodName;
ControlSheetTooltipUpdater.ItemSlotId= getInventory().getItemSlotId(ctrlSheet);
ControlSheetTooltipUpdater.CtrlSheet = ctrlSheet;
// Add the waiter
getInventory().addItemInfoWaiter(&ControlSheetTooltipUpdater);
}
help = ControlSheetTooltipUpdater.infoValidated(ctrlSheet, luaMethodName);
help = _ItemInfoWaiter.infoValidated();
return;
}
}
@ -3551,6 +3716,10 @@ void CDBCtrlSheet::resetAllTexIDs()
_Stackable= 1;
_IconW = 0;
_IconH = 0;
_ItemInfoChanged = true;
_EnchantIcons.clear();
_BuffIcons.clear();
}

@ -37,7 +37,7 @@
#include "game_share/item_family.h"
//
#include "../time_client.h"
#include "item_info_waiter.h"
class CItemSheet;
class CPactSheet;
@ -53,6 +53,25 @@ namespace NLGUI
class CViewRenderer;
}
class CDBCtrlSheet;
// ***************************************************************************
// Item info request from server
class CControlSheetInfoWaiter : public IItemInfoWaiter
{
public:
CDBCtrlSheet* CtrlSheet;
string LuaMethodName;
bool Requesting;
CControlSheetInfoWaiter()
: IItemInfoWaiter(), Requesting(false)
{ }
public:
ucstring infoValidated() const;
void sendRequest();
virtual void infoReceived();
};
// ***************************************************************************
/** Common info for CDBCtrlSheet and CDBGroupListSheet
@ -580,8 +599,10 @@ public:
// start notify anim (at the end of regen usually)
void startNotifyAnim();
protected:
// callback from info waiter
void infoReceived();
protected:
inline bool useItemInfoForFamily(ITEMFAMILY::EItemFamily family) const;
void setupItem();
@ -622,6 +643,7 @@ protected:
NLMISC::CCDBNodeLeaf *_ItemRMFaberStatType;
mutable sint32 _LastSheetId;
bool _ItemInfoChanged;
/// Display
sint32 _DispSlotBmpId; // Display slot bitmap id
@ -632,6 +654,26 @@ protected:
sint32 _DispOverBmpId; // Over Icon
sint32 _DispOver2BmpId; // Over Icon N0 2 for bricks / items. Useful for items when _DispOverBmpId is used to paint user color on the item.
std::string _HpBuffIcon;
std::string _SapBuffIcon;
std::string _StaBuffIcon;
std::string _FocusBuffIcon;
// texture ids to show
struct SBuffIcon
{
SBuffIcon(sint32 txid, NLMISC::CRGBA col=NLMISC::CRGBA::White)
:TextureId(txid), Color(col), IconW(0), IconH(0)
{ }
sint32 TextureId;
NLMISC::CRGBA Color;
sint32 IconW;
sint32 IconH;
};
std::vector<SBuffIcon> _BuffIcons;
std::vector<SBuffIcon> _EnchantIcons;
// Level Brick or Quality
union
{
@ -751,6 +793,7 @@ protected:
sint64 _NotifyAnimEndTime;
CControlSheetInfoWaiter _ItemInfoWaiter;
private:
mutable TSheetType _ActualType;
@ -769,6 +812,9 @@ private:
// special for items
void updateItemCharacRequirement(sint32 sheetId);
// Send ITEM_INFO:GET request to server to fetch Buffs, Enchant info
void setupItemInfoWaiter();
// update armour color, and cache
void updateArmourColor(sint8 col);

@ -58,6 +58,8 @@
using namespace std;
using namespace NLMISC;
extern TSessionId CharacterHomeSessionId;
extern NLMISC::CLog g_log;
// Context help
extern void contextHelp (const std::string &help);
@ -127,6 +129,8 @@ CItemImage::CItemImage()
Sheet = NULL;
Quality = NULL;
Quantity = NULL;
CreateTime = NULL;
Serial = NULL;
UserColor = NULL;
Price = NULL;
Weight= NULL;
@ -141,6 +145,8 @@ void CItemImage::build(CCDBNodeBranch *branch)
Sheet = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("SHEET"), false));
Quality = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("QUALITY"), false));
Quantity = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("QUANTITY"), false));
CreateTime = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("CREATE_TIME"), false));
Serial = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("SERIAL"), false));
UserColor = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("USER_COLOR"), false));
Price = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("PRICE"), false));
Weight = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("WEIGHT"), false));
@ -149,7 +155,145 @@ void CItemImage::build(CCDBNodeBranch *branch)
ResaleFlag = dynamic_cast<CCDBNodeLeaf *>(branch->getNode(ICDBNode::CTextId("RESALE_FLAG"), false));
// Should always have at least those one:(ie all but Price)
nlassert(Sheet && Quality && Quantity && UserColor && Weight && NameId && InfoVersion);
nlassert(Sheet && Quality && Quantity && CreateTime && Serial && UserColor && Weight && NameId && InfoVersion);
}
uint64 CItemImage::getItemId() const
{
return ((uint64)getSerial() << 32) | getCreateTime();
}
// *************************************************************************************************
void CItemInfoCache::load(const std::string &filename)
{
try
{
CIFile f;
if (f.open(filename))
{
serial(f);
}
} catch(...)
{ }
}
void CItemInfoCache::save(const std::string &filename)
{
try
{
COFile f;
if (f.open(filename))
{
serial(f);
}
}catch(...)
{ }
}
void CItemInfoCache::serial(NLMISC::IStream &s)
{
s.serialCheck(NELID("METI"));
uint ver = 1;
s.serialVersion(ver);
uint8 byte = 1;
if (s.isReading())
{
_ItemInfoCacheMap.clear();
while(true)
{
uint64 key;
s.serial(byte);
if (byte == 0)
{
break;
}
s.serial(key);
s.serial(_ItemInfoCacheMap[key].CacheCycle);
_ItemInfoCacheMap[key].serial(s);
// these are not used in item info cache
_ItemInfoCacheMap[key].InfoVersionFromMsg = 0;
_ItemInfoCacheMap[key].InfoVersionFromSlot = 0;
_ItemInfoCacheMap[key].InfoVersionSlotServerWaiting = 0;
}
}
else
{
byte = 1;
TItemInfoCacheMap::iterator it = _ItemInfoCacheMap.begin();
while (it != _ItemInfoCacheMap.end())
{
// purge item from cache if not encountered in X save
if (it->second.CacheCycle < 10000)
{
// 'record exists' byte
s.serial(byte);
// item id (serial << 32 | createTime)
uint64 key = it->first;
s.serial(key);
uint32 cycle = it->second.CacheCycle+1;
s.serial(cycle);
// item info
it->second.serial(s);
}
++it;
}
// eof of records byte
byte = 0;
s.serial(byte);
}
}
const CClientItemInfo *CItemInfoCache::getItemInfo(uint32 serial, uint32 createTime) const
{
if (serial > 0 && createTime > 0)
{
uint64 itemId = ((uint64)serial << 32) | createTime;
return getItemInfo(itemId);
}
return NULL;
}
const CClientItemInfo *CItemInfoCache::getItemInfo(uint64 itemId) const
{
if (itemId > 0)
{
TItemInfoCacheMap::const_iterator it = _ItemInfoCacheMap.find(itemId);
if (it != _ItemInfoCacheMap.end())
return &(it->second);
}
return NULL;
}
void CItemInfoCache::readFromImpulse(uint64 itemId, CItemInfos itemInfo)
{
if (itemId > 0)
{
_ItemInfoCacheMap[itemId].readFromImpulse(itemInfo);
_ItemInfoCacheMap[itemId].CacheCycle = 0;
}
}
void CItemInfoCache::debugItemInfoCache() const
{
nlinfo("ItemInfoCache: %d entries", _ItemInfoCacheMap.size());
uint count = 0;
for (auto it = _ItemInfoCacheMap.begin(); it != _ItemInfoCacheMap.end(); ++it)
{
uint32 serial = (it->first >> 32) & 0xFFFFFFFF;
uint32 created = it->first & 0xFFFFFFFF;
nlinfo("[%-4d] cacheCycle:%d, serial:%d, createTime:%d", count++, it->second.CacheCycle, serial, created);
}
CInterfaceManager *pIM= CInterfaceManager::getInstance();
pIM->displaySystemInfo(toString("ItemInfoCache: %d entries written to client.log", _ItemInfoCacheMap.size()));
}
// *************************************************************************************************
@ -180,12 +324,16 @@ CInventoryManager::CInventoryManager()
BagItemEquipped[i]= false;
}
_ItemInfoCacheFilename = toString("save/item_infos_%d.cache", CharacterHomeSessionId.asInt());
_ItemInfoCache.load(_ItemInfoCacheFilename);
nlctassert(NumInventories== sizeof(InventoryIndexes)/sizeof(InventoryIndexes[0]));
}
// ***************************************************************************
CInventoryManager::~CInventoryManager()
{
_ItemInfoCache.save(_ItemInfoCacheFilename);
}
// *************************************************************************************************
@ -257,6 +405,11 @@ CItemImage &CInventoryManager::getServerBagItem(uint index)
nlassert(index < MAX_BAGINV_ENTRIES);
return ServerBag[index];
}
const CItemImage &CInventoryManager::getServerBagItem(uint index) const
{
nlassert(index < MAX_BAGINV_ENTRIES);
return ServerBag[index];
}
// *************************************************************************************************
CItemImage &CInventoryManager::getServerTempItem(uint index)
@ -264,6 +417,11 @@ CItemImage &CInventoryManager::getServerTempItem(uint index)
nlassert(index < MAX_TEMPINV_ENTRIES);
return ServerTempInv[index];
}
const CItemImage &CInventoryManager::getServerTempItem(uint index) const
{
nlassert(index < MAX_TEMPINV_ENTRIES);
return ServerTempInv[index];
}
// *************************************************************************************************
CItemImage *CInventoryManager::getServerHandItem(uint index)
@ -3262,22 +3420,53 @@ uint CInventoryManager::getItemSheetForSlotId(uint slotId) const
return 0;
}
// ***************************************************************************
const CClientItemInfo *CInventoryManager::getItemInfoCache(uint32 serial, uint32 createTime) const
{
return _ItemInfoCache.getItemInfo(serial, createTime);
}
// ***************************************************************************
const CClientItemInfo &CInventoryManager::getItemInfo(uint slotId) const
{
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
static CClientItemInfo empty;
if(it==_ItemInfoMap.end())
if (it == _ItemInfoMap.end() || !isItemInfoUpToDate(slotId))
{
// if slot has not been populated yet or out of date, then return info from cache if possible
const CItemImage *item = getServerItem(slotId);
if (item && item->getItemId() > 0) {
const CClientItemInfo *ret = _ItemInfoCache.getItemInfo(item->getItemId());
if (ret != NULL)
{
return *ret;
}
}
}
if (it == _ItemInfoMap.end())
{
return empty;
else
return it->second;
}
return it->second;
}
// ***************************************************************************
bool CInventoryManager::isItemInfoUpToDate(uint slotId)
bool CInventoryManager::isItemInfoAvailable(uint slotId) const
{
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
return it != _ItemInfoMap.end();
}
// ***************************************************************************
bool CInventoryManager::isItemInfoUpToDate(uint slotId) const
{
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
if (it == _ItemInfoMap.end())
return true;
// true if the version already matches
return getItemInfo(slotId).InfoVersionFromMsg == getItemInfo(slotId).InfoVersionFromSlot;
return it->second.InfoVersionFromMsg == it->second.InfoVersionFromSlot;
}
// ***************************************************************************
@ -3314,8 +3503,10 @@ void CInventoryManager::removeItemInfoWaiter(IItemInfoWaiter *waiter)
void CInventoryManager::updateItemInfoWaiters(uint itemSlotId)
{
// First verify if the versions matches. If differ, no need to update waiters since not good.
if(getItemInfo(itemSlotId).InfoVersionFromMsg != getItemInfo(itemSlotId).InfoVersionFromSlot)
if (!isItemInfoUpToDate(itemSlotId))
{
return;
}
bool isItemFromTrading= (itemSlotId>>CItemInfos::SlotIdIndexBitSize)==INVENTORIES::trading;
@ -3409,10 +3600,15 @@ void CInventoryManager::onReceiveItemSheet(ICDBNode* node)
// ***************************************************************************
void CInventoryManager::onReceiveItemInfo(const CItemInfos &itemInfo)
{
uint itemSlotId;
// update the Info
itemSlotId= itemInfo.slotId;
uint itemSlotId = itemInfo.slotId;
const CItemImage *item = getServerItem(itemSlotId);
if (item && item->getItemId() > 0)
{
_ItemInfoCache.readFromImpulse(item->getItemId(), itemInfo);
}
// write in map, from DB.
_ItemInfoMap[itemSlotId].readFromImpulse(itemInfo);
@ -3426,7 +3622,7 @@ void CInventoryManager::onReceiveItemInfo(const CItemInfos &itemInfo)
// ***************************************************************************
void CInventoryManager::onRefreshItemInfoVersion(uint16 slotId, uint8 infoVersion)
{
_ItemInfoMap[slotId].refreshInfoVersion( infoVersion );
_ItemInfoMap[slotId].refreshInfoVersion(infoVersion);
}
// ***************************************************************************
@ -3522,6 +3718,12 @@ void CInventoryManager::debugItemInfoWaiters()
}
}
// ***************************************************************************
void CInventoryManager::debugItemInfoCache() const
{
_ItemInfoCache.debugItemInfoCache();
}
// ***************************************************************************
void CInventoryManager::sortBag()
{
@ -3677,6 +3879,14 @@ CItemImage &CInventoryManager::getServerPAItem(uint beastIndex, uint index)
return ServerPAInv[beastIndex][index];
}
const CItemImage &CInventoryManager::getServerPAItem(uint beastIndex, uint index) const
{
nlassert(beastIndex < MAX_INVENTORY_ANIMAL);
nlassert(index < MAX_ANIMALINV_ENTRIES);
return ServerPAInv[beastIndex][index];
}
// ***************************************************************************
CItemImage &CInventoryManager::getLocalItem(uint inv, uint index)
{
@ -3703,6 +3913,93 @@ CItemImage &CInventoryManager::getServerItem(uint inv, uint index)
return dummy;
}
// ***************************************************************************
const CItemImage *CInventoryManager::getServerItem(uint slotId) const
{
uint inv, index;
getSlotInvIndex(slotId, inv, index);
if (inv == INVENTORIES::bag)
{
return &getServerBagItem(index);
}
else if (inv >= INVENTORIES::pet_animal && inv <INVENTORIES::pet_animal+MAX_INVENTORY_ANIMAL)
{
return &getServerPAItem(inv-INVENTORIES::pet_animal, index);
}
else if (inv == INVENTORIES::temporary)
{
return &getServerTempItem(index);
}
else if (inv == INVENTORIES::guild)
{
// player is in guild outpost or in guild hall
if (getInventory().isInventoryAvailable(INVENTORIES::guild))
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("SERVER:GUILD:INVENTORY:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
return NULL;
}
else if (inv == INVENTORIES::player_room)
{
// player is in their room
if (getInventory().isInventoryAvailable(INVENTORIES::player_room))
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch(SERVER_INVENTORY ":ROOM:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
return NULL;
}
else if (inv == INVENTORIES::trading)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:TRADING:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else if (inv == INVENTORIES::exchange)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:EXCHANGE:GIVE:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else if (inv == INVENTORIES::exchange_proposition)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:EXCHANGE:RECEIVE:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else
{
nlwarning("getServerItem: invalid inventory %d for slotId %d", inv, slotId);
}
// invalid inventory
return NULL;
}
// ***************************************************************************
CInventoryManager::TInvType CInventoryManager::invTypeFromString(const string &str)
{
@ -3719,3 +4016,11 @@ CInventoryManager::TInvType CInventoryManager::invTypeFromString(const string &s
if (sTmp == "inv_room") return InvRoom;
return InvUnknown;
}
// ***************************************************************************
void CInventoryManager::getSlotInvIndex(uint slotId, uint &inv, uint &index) const
{
inv = slotId >> CItemInfos::SlotIdIndexBitSize;
index = slotId & CItemInfos::SlotIdIndexBitMask;
}

@ -31,7 +31,7 @@ namespace NLMISC{
class CCDBNodeBranch;
}
class CDBCtrlSheet;
class IItermInfoWaiter;
const uint MAX_TEMPINV_ENTRIES = INVENTORIES::NbTempInvSlots;
const uint MAX_BAGINV_ENTRIES = INVENTORIES::NbBagSlots;
@ -60,6 +60,8 @@ public:
NLMISC::CCDBNodeLeaf *Sheet;
NLMISC::CCDBNodeLeaf *Quality;
NLMISC::CCDBNodeLeaf *Quantity;
NLMISC::CCDBNodeLeaf *CreateTime;
NLMISC::CCDBNodeLeaf *Serial;
NLMISC::CCDBNodeLeaf *UserColor;
NLMISC::CCDBNodeLeaf *Price;
NLMISC::CCDBNodeLeaf *Weight;
@ -72,10 +74,13 @@ public:
CItemImage();
// build from a branch
void build(NLMISC::CCDBNodeBranch *branch);
uint64 getItemId() const;
// shortcuts to avoid NULL pointer tests
uint32 getSheetID() const { return (uint32) (Sheet ? Sheet->getValue32() : 0); }
uint16 getQuality() const { return (uint16) (Quality ? Quality->getValue16() : 0); }
uint16 getQuantity() const { return (uint16) (Quantity ? Quantity->getValue16() : 0); }
uint32 getCreateTime() const { return (uint32) (CreateTime ? CreateTime->getValue32() : 0); }
uint32 getSerial() const { return (uint32) (Serial ? Serial->getValue32() : 0); }
uint8 getUserColor() const { return (uint8) (UserColor ? UserColor->getValue16() : 0); }
uint32 getPrice() const { return (uint32) (Price ? Price->getValue32() : 0); }
uint32 getWeight() const { return (uint32) (Weight ? Weight->getValue32() : 0); }
@ -87,6 +92,8 @@ public:
void setSheetID(uint32 si) { if (Sheet) Sheet->setValue32((sint32) si); }
void setQuality(uint16 quality) { if (Quality) Quality->setValue16((sint16) quality); }
void setQuantity(uint16 quantity) { if (Quantity) Quantity->setValue16((sint16) quantity); }
void setCreateTime(uint32 create_time) { if (CreateTime) CreateTime->setValue32((sint32) create_time); }
void setSerial(uint32 serial) { if (Serial) Serial->setValue32((sint32) serial); }
void setUserColor(uint8 uc) { if (UserColor) UserColor->setValue8((sint8) uc); }
void setPrice(uint32 price) { if (Price) Price->setValue32((sint32) price); }
void setWeight(uint32 wgt) { if (Weight) Weight->setValue32((sint32) wgt); }
@ -108,11 +115,15 @@ public:
// This is the InfoVersionFromSlot when last request was sent to server
uint16 InfoVersionSlotServerWaiting;
// Used to track cache age (reset on use, +1 on every save)
uint32 CacheCycle;
CClientItemInfo()
{
InfoVersionFromMsg= 0;
InfoVersionFromSlot= 0;
InfoVersionSlotServerWaiting= 0;
CacheCycle= 0;
}
/// Set InfoVersion from Info message (info requested by the player)
@ -122,21 +133,25 @@ public:
void refreshInfoVersion(uint8 infoVersion) { InfoVersionFromMsg= infoVersion; }
};
class IItemInfoWaiter
class CItemInfoCache
{
public:
IItemInfoWaiter() {ItemSlotId= 0; ItemSheet= 0;}
virtual ~IItemInfoWaiter() {}
// The item SheetId. If differ from current sheet in the SlotId, the infos are not updated / requested
uint ItemSheet;
// The item SlotId to retrieve info.
uint ItemSlotId;
// Called when the info is received for this slot.
virtual void infoReceived() =0;
};
void load(const std::string &filename);
void save(const std::string &filename);
void serial(NLMISC::IStream &s);
// retrieve pointer to item info or null if error
const CClientItemInfo *getItemInfo(uint32 serial, uint32 createTime) const;
const CClientItemInfo *getItemInfo(uint64 itemId) const;
// set/update item info in cache
void readFromImpulse(uint64 itemId, CItemInfos itemInfo);
void debugItemInfoCache() const;
private:
typedef std::map<uint64, CClientItemInfo> TItemInfoCacheMap;
TItemInfoCacheMap _ItemInfoCacheMap;
};
// ***************************************************************************
/** This manager gives direct access to inventory slots (bag, temporary inventory, hands, and equip inventory)
@ -189,8 +204,10 @@ public:
// SERVER INVENTORY
// get item of bag (local inventory)
CItemImage &getServerBagItem(uint index);
const CItemImage &getServerBagItem(uint index) const;
// get temporary item (local inventory)
CItemImage &getServerTempItem(uint index);
const CItemImage &getServerTempItem(uint index) const;
// get hand item (local inventory)
CItemImage *getServerHandItem(uint index);
// get equip item (local inventory)
@ -200,8 +217,11 @@ public:
void setServerMoney(uint64 value);
// get item of pack animal (server inventory). beastIndex ranges from 0 to MAX_INVENTORY_ANIMAL-1
CItemImage &getServerPAItem(uint beastIndex, uint index);
const CItemImage &getServerPAItem(uint beastIndex, uint index) const;
// get the item Image for the given inventory. assert if bad inventory
CItemImage &getServerItem(uint inv, uint index);
// get the item Image for the given slotId or NULL if bad
const CItemImage *getServerItem(uint slotId) const;
// Drag'n'Drop Management
enum TFrom { Slot, TextList, IconList, Nowhere };
@ -267,9 +287,13 @@ public:
uint16 getItemSlotId(CDBCtrlSheet *ctrl);
uint16 getItemSlotId(const std::string &itemDb, uint slotIndex);
const CClientItemInfo &getItemInfo(uint slotId) const;
// get item info from cache
const CClientItemInfo *getItemInfoCache(uint32 serial, uint32 createTime) const;
uint getItemSheetForSlotId(uint slotId) const;
// Returns true if the item info is already in slot cache
bool isItemInfoAvailable(uint slotId) const;
// Returns true if the item info version already matches
bool isItemInfoUpToDate(uint slotId);
bool isItemInfoUpToDate(uint slotId) const;
// Add a Waiter on ItemInfo (ItemHelp opening). no-op if here, but reorder (returns true if the version already matches or if waiter is NULL)
void addItemInfoWaiter(IItemInfoWaiter *waiter);
// remove a Waiter on ItemInfo (ItemHelp closing). no-op if not here. NB: no delete
@ -279,6 +303,7 @@ public:
void onRefreshItemInfoVersion(uint16 slotId, uint8 infoVersion);
// Log for debug
void debugItemInfoWaiters();
void debugItemInfoCache() const;
void sortBag();
@ -294,6 +319,9 @@ public:
enum TInvType { InvBag, InvPA0, InvPA1, InvPA2, InvPA3, InvPA4, InvPA5, InvPA6, InvGuild, InvRoom, InvUnknown };
static TInvType invTypeFromString(const std::string &str);
// inventory and slot from slotId
void getSlotInvIndex(uint slotId, uint &inv, uint &index) const;
private:
// LOCAL INVENTORY
@ -318,7 +346,9 @@ private:
CDBCtrlSheet *DNDCurrentItem;
// ItemExtraInfo management.
typedef std::map<uint, CClientItemInfo> TItemInfoMap;
std::string _ItemInfoCacheFilename;
CItemInfoCache _ItemInfoCache;
typedef std::map<uint, CClientItemInfo> TItemInfoMap;
TItemInfoMap _ItemInfoMap;
typedef std::list<IItemInfoWaiter*> TItemInfoWaiters;
TItemInfoWaiters _ItemInfoWaiters;

@ -0,0 +1,39 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef RZ_ITEM_INFO_WAITER_H
#define RZ_ITEM_INFO_WAITER_H
class IItemInfoWaiter
{
public:
IItemInfoWaiter() {ItemSlotId= 0; ItemSheet= 0;}
virtual ~IItemInfoWaiter() {}
// The item SheetId. If differ from current sheet in the SlotId, the infos are not updated / requested
uint ItemSheet;
// The item SlotId to retrieve info.
uint ItemSlotId;
// Called when the info is received for this slot.
virtual void infoReceived() =0;
};
#endif // RZ_DBCTRL_SHEET_INFO_WAITER_H
/* End of item_info_waiter.h */

@ -161,6 +161,8 @@ bool CHugeListObs::init()
case Trading:
_Items[k].SlotType = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SLOT_TYPE").c_str(), (int) k), false);
_Items[k].Quality = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:QUALITY").c_str(), (int) k), false);
_Items[k].Serial = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SERIAL").c_str(), (int) k), false);
_Items[k].CreateTime = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:CREATE_TIME").c_str(), (int) k), false);
_Items[k].SheetIDOrSkill = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SHEET").c_str(), (int) k), false);
_Items[k].Price = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:PRICE").c_str(), (int) k), false);
_Items[k].Weight = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:WEIGHT").c_str(), (int) k), false);
@ -181,6 +183,7 @@ bool CHugeListObs::init()
if ((_Items[k].SlotType == NULL) || (_Items[k].Quality == NULL) || (_Items[k].SheetIDOrSkill == NULL) ||
(_Items[k].Price == NULL) || (_Items[k].Weight==NULL) || (_Items[k].InfoVersion==NULL) ||
(_Items[k].UserColor==NULL) || (_Items[k].NameId==NULL) || (_Items[k].Quantity==NULL) ||
(_Items[k].Serial == NULL) || (_Items[k].CreateTime == NULL) ||
(_Items[k].PriceRetire==NULL) || (_Items[k].SellerType==NULL) || (_Items[k].ResaleTimeLeft==NULL) ||
(_Items[k].VendorNameId==NULL) || (_Items[k].Enchant ==NULL) || (_Items[k].RMClassType == NULL) ||
(_Items[k].RMFaberStatType == NULL) || (_Items[k].PrerequisitValid == NULL) ||
@ -191,6 +194,8 @@ bool CHugeListObs::init()
case ItemForMissions:
_Items[k].SlotType = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SLOT_TYPE").c_str(), (int) k), false);
_Items[k].Quality = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:QUALITY").c_str(), (int) k), false);
_Items[k].Serial = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SERIAL").c_str(), (int) k), false);
_Items[k].CreateTime = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:CREATE_TIME").c_str(), (int) k), false);
_Items[k].SheetIDOrSkill = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:SHEET").c_str(), (int) k), false);
_Items[k].LogicTextID = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:LOGIC_TEXT_ID").c_str(), (int) k), false);
_Items[k].DescTextID = NLGUI::CDBManager::getInstance()->getDbProp(toString((dbPath + ":%d:DESC_TEXT_ID").c_str(), (int) k), false);
@ -205,7 +210,7 @@ bool CHugeListObs::init()
(_Items[k].LogicTextID == NULL) || (_Items[k].DescTextID == NULL) ||
(_Items[k].Weight==NULL) || (_Items[k].InfoVersion==NULL) || (_Items[k].UserColor==NULL) ||
(_Items[k].Enchant ==NULL) || (_Items[k].RMClassType == NULL) || (_Items[k].RMFaberStatType == NULL) ||
(_Items[k].NameId==NULL)
(_Items[k].NameId==NULL) || (_Items[k].Serial == NULL) || (_Items[k].CreateTime == NULL)
)
return false;
break;
@ -383,6 +388,8 @@ void CHugeListObs::update(ICDBNode * /* node */)
{
page.Items[k].SlotType = (TRADE_SLOT_TYPE::TTradeSlotType) _Items[k].SlotType->getValue32();
page.Items[k].Quality = (uint16) _Items[k].Quality->getValue16();
page.Items[k].Serial = (uint32) _Items[k].Serial->getValue32();
page.Items[k].CreateTime = (uint32) _Items[k].CreateTime->getValue32();
page.Items[k].SheetIDOrSkill = (uint32) _Items[k].SheetIDOrSkill->getValue32();
page.Items[k].Price = (uint32) _Items[k].Price->getValue32();
page.Items[k].Weight= (uint16) _Items[k].Weight->getValue16();
@ -420,6 +427,8 @@ void CHugeListObs::update(ICDBNode * /* node */)
case ItemForMissions:
page.Items[k].SlotType = (TRADE_SLOT_TYPE::TTradeSlotType) _Items[k].SlotType->getValue32();
page.Items[k].Quality = (uint16) _Items[k].Quality->getValue16();
page.Items[k].Serial = (uint32) _Items[k].Serial->getValue32();
page.Items[k].CreateTime = (uint32) _Items[k].CreateTime->getValue32();
page.Items[k].SheetIDOrSkill = (uint32) _Items[k].SheetIDOrSkill->getValue32();
page.Items[k].LogicTextID = (uint32) _Items[k].LogicTextID->getValue32();
page.Items[k].DescTextID = (uint32) _Items[k].DescTextID->getValue32();
@ -569,6 +578,10 @@ void CHugeListObs::updateUIItemPage(uint index)
case Trading:
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":QUALITY", false);
if (leaf) leaf->setValue32(currItem.Quality);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SERIAL", false);
if (leaf) leaf->setValue32(currItem.Serial);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":CREATE_TIME", false);
if (leaf) leaf->setValue32(currItem.CreateTime);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SLOT_TYPE", false);
if (leaf) leaf->setValue32(currItem.SlotType);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SHEET", false);
@ -610,6 +623,10 @@ void CHugeListObs::updateUIItemPage(uint index)
case ItemForMissions:
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":QUALITY", false);
if (leaf) leaf->setValue32(currItem.Quality);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SERIAL", false);
if (leaf) leaf->setValue32(currItem.Serial);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":CREATE_TIME", false);
if (leaf) leaf->setValue32(currItem.CreateTime);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SLOT_TYPE", false);
if (leaf) leaf->setValue32(currItem.SlotType);
leaf = NLGUI::CDBManager::getInstance()->getDbProp(dbPath + toString(k + index * TRADE_PAGE_NUM_ITEMS) + ":SHEET", false);

@ -124,6 +124,8 @@ private:
//
NLMISC::CCDBNodeLeaf *SlotType;
NLMISC::CCDBNodeLeaf *Quality;
NLMISC::CCDBNodeLeaf *Serial;
NLMISC::CCDBNodeLeaf *CreateTime;
NLMISC::CCDBNodeLeaf *SheetIDOrSkill;
//
NLMISC::CCDBNodeLeaf *LogicTextID; // valid if the item is to be obtained for a mission
@ -157,6 +159,8 @@ private:
GuildName(NULL),
SlotType(NULL),
Quality(NULL),
Serial(NULL),
CreateTime(NULL),
SheetIDOrSkill(NULL),
LogicTextID(NULL),
DescTextID(NULL),
@ -216,6 +220,8 @@ private:
TRADE_SLOT_TYPE::TTradeSlotType SlotType;
uint16 Quality;
uint32 Serial;
uint32 CreateTime;
uint32 SheetIDOrSkill;
uint32 LogicTextID; // Valid if the item is to be obtained as a mission reward
uint32 DescTextID; // Valid if the item is to be obtained as a mission reward

Loading…
Cancel
Save