Changed: Display stat buff and enchant info on item icon

--HG--
branch : feature-item-icon-buffs
hg/atys
Nimetu 6 years ago
parent e0a1cd3c4a
commit 2f883ddb1d

@ -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);
@ -203,7 +203,7 @@ int CDBCtrlSheet::luaGetCreatorName(CLuaState &ls)
ucstring creatorName;
STRING_MANAGER::CStringManagerClient::instance()->getString(itemInfo.CreatorName, creatorName);
CLuaIHM::push(ls, creatorName);
return 1;
}
@ -236,7 +236,6 @@ int CDBCtrlSheet::luaWaitInfo(CLuaState &ls)
// ***************************************************************************
int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
@ -257,7 +256,7 @@ int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
}
}
// Reset other to 0.
for(;;currentBrick++)
{
@ -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();
}
}
@ -1857,7 +1952,7 @@ void CDBCtrlSheet::draw()
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CViewRenderer &rVR = *CViewRenderer::getInstance();
if (_Type != SheetType_Macro)
{
if (_LastSheetId != _SheetId.getSInt32())
@ -1949,13 +2044,13 @@ void CDBCtrlSheet::draw()
rVR.getTextureSizeFromId(frontTex, texWidth, texHeight);
CQuadUV regenTris[5];
uint numTris = buildPie(regenTris, 0.f, amount, texWidth);
uint numTris = buildPie(regenTris, 0.f, amount, texWidth);
nlassert(numTris <= sizeofarray(regenTris));
for (uint tri = 0; tri < numTris; ++tri)
{
rVR.drawQuad(_RenderLayer + 1, regenTris[tri], frontTex, CRGBA::White, false);
}
numTris = buildPie(regenTris, amount, 1.f, texWidth);
numTris = buildPie(regenTris, amount, 1.f, texWidth);
nlassert(numTris <= sizeofarray(regenTris));
for (uint tri = 0; tri < numTris; ++tri)
{
@ -1977,7 +2072,7 @@ void CDBCtrlSheet::draw()
if (texId != -1)
{
sint32 texWidth, texHeight;
rVR.getTextureSizeFromId(texId, texWidth, texHeight);
rVR.getTextureSizeFromId(texId, texWidth, texHeight);
const float freq0 = 1.f;
const float phase0 = 0.f;
const float freq1 = -1.f;
@ -1994,20 +2089,20 @@ void CDBCtrlSheet::draw()
// ----------------------------------------------------------------------------
void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 texId, sint32 texWidth, sint32 texHeight)
{
NLMISC::CQuadUV quv;
NLMISC::CQuadUV quv;
float cosA = cosf(angle);
float sinA = sinf(angle);
//
quv.V0.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA + sinA),
quv.V0.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA + sinA),
_YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA - cosA), 0.5f);
//
quv.V1.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA + sinA),
quv.V1.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA + sinA),
_YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA - cosA), 0.5f);
//
quv.V2.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA - sinA),
_YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA + cosA), 0.5f);
quv.V2.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA - sinA),
_YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA + cosA), 0.5f);
//
quv.V3.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA - sinA),
quv.V3.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA - sinA),
_YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA + cosA), 0.5f);
//
quv.Uv0.set(0.f, 0.f);
@ -2022,13 +2117,13 @@ void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale,
// ----------------------------------------------------------------------------
inline void CDBCtrlSheet::uvToScreen(float x, float y, CVector &screenPos, uint texSize) const
{
screenPos.set(_XReal + texSize * x, _YReal + texSize * (1.f - y), 0.5f);
screenPos.set(_XReal + texSize * x, _YReal + texSize * (1.f - y), 0.5f);
}
// ----------------------------------------------------------------------------
void CDBCtrlSheet::buildPieCorner(float angle, CUV &uv, CVector &pos, uint texSize) const
{
{
float radAngle = angle * 2.f * float(NLMISC::Pi);
// angle origin is at 12'o'clock
float x = cosf(0.5f * float(NLMISC::Pi) - radAngle);
@ -2061,33 +2156,33 @@ void CDBCtrlSheet::buildPieCorner(float angle, CUV &uv, CVector &pos, uint texSi
y /= -x;
x = -1.f;
}
}
}
// remap to unit quad
// (well we could have worked with tan() too, I find it simpler this way ....)
uv.set(0.5f * x + 0.5f, 0.5f - 0.5f * y);
uvToScreen(uv.U, uv.V, pos, texSize);
uvToScreen(uv.U, uv.V, pos, texSize);
}
// ----------------------------------------------------------------------------
uint CDBCtrlSheet::buildPie(CQuadUV *triPtr, float startAngle, float endAngle, uint texSize)
{
{
static volatile bool exit1 = false;
nlassert(startAngle <= endAngle);
const sint32 factor = 65536;
const float invFactor = 1.f / factor;
const sint32 factor = 65536;
const float invFactor = 1.f / factor;
sint32 iCurr = (uint32) (startAngle * factor) ;
sint32 iEnd = (uint32) (endAngle * factor);
clamp(iCurr, 0, factor);
clamp(iEnd, 0, factor);
uint triCount = 0;
CVector quadCenter;
uvToScreen(0.5f, 0.5f, quadCenter, texSize);
uvToScreen(0.5f, 0.5f, quadCenter, texSize);
while (iCurr != iEnd)
{
sint32 iNext = iCurr + (factor / 4);
iNext -= ((iNext - factor / 8) % (factor / 4)); // snap to nearest corner
iNext = std::min(iNext, iEnd);
iNext -= ((iNext - factor / 8) % (factor / 4)); // snap to nearest corner
iNext = std::min(iNext, iEnd);
// well, not really a quad, but we don't have yet simple triangles rendering in the ui
triPtr->Uv0.set(0.5f, 0.5f);
triPtr->V0 = quadCenter;
@ -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);
@ -2348,8 +2497,8 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
case SheetType_SPhrase : setupSPhrase(); break;
default: nlassert(true); break;
}
bool showOutOfRangeSymbol = false;
bool forceGrayed = false;
@ -2361,15 +2510,15 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
{
CSPhraseManager *pPM= CSPhraseManager::getInstance();
const CSPhraseCom &phrase= pPM->getPhrase(phraseId);
// get the phrase Data version, to check if it had changed.
// get the phrase Data version, to check if it had changed.
uint32 totalActionMalus = pPM->getTotalActionMalus(phrase);
uint8 targetSlot = UserEntity->targetSlot();
if (targetSlot < CLFECOMMON::INVALID_SLOT)
{
CEntityCL *target = EntitiesMngr.entity(targetSlot);
if (target && UserEntity)
{
double dist2 = (target->pos() - UserEntity->pos()).sqrnorm();
{
double dist2 = (target->pos() - UserEntity->pos()).sqrnorm();
CSBrickManager *pBM= CSBrickManager::getInstance();
CSBrickSheet *rootBrick= NULL;
if(phrase.Bricks.size())
@ -2396,7 +2545,7 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
break;
}
}
if (!isPrimalMagic)
{
forceGrayed = !(target->isPlayer() && target->isFriend());
@ -2405,21 +2554,21 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
{
forceGrayed = false;
}
}
if (!forceGrayed)
{
sint phraseRange;
sint rangeMalus;
pPM->getPhraseMagicRange(phrase, totalActionMalus, phraseRange, rangeMalus);
double rangeDist = (float) (phraseRange + rangeMalus);
double rangeDist = (float) (phraseRange + rangeMalus);
if (phraseRange != 0) // if range is '0' then it is a 'self' action
{
rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
if (dist2 > rangeDist * rangeDist)
{
showOutOfRangeSymbol = true;
showOutOfRangeSymbol = true;
}
}
}
@ -2451,11 +2600,11 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
if (isTaunt && !forceGrayed)
{
double rangeDist = (float) maxRange;
rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
double rangeDist = (float) maxRange;
rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
if (dist2 > rangeDist * rangeDist)
{
showOutOfRangeSymbol = true;
showOutOfRangeSymbol = true;
}
}
}
@ -2522,15 +2671,15 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
// if the pointer is over the button
if (_Over)
// Draw -1,-1 because the slot over is 26x26
rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
}
if (showOutOfRangeSymbol)
{
{
rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::OutOfRangeTexture), CRGBA::White);
}
}
}
break;
break;
case CCtrlSheetInfo::SheetType_OutpostBuilding:
setupOutpostBuilding();
if (_DispBackBmpId != -1)
@ -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;
@ -3247,18 +3426,18 @@ void CDBCtrlSheet::getContextHelp(ucstring &help) const
}
else
{
// delegate setup of context he help ( & window ) to lua
// delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= CLuaManager::getInstance().getLuaState();
{
CLuaStackRestorer lsr(ls, 0);
CSPhraseManager *pPM= CSPhraseManager::getInstance();
CSPhraseManager *pPM= CSPhraseManager::getInstance();
_PhraseAdapter = new CSPhraseComAdpater;
_PhraseAdapter->Phrase = pPM->getPhrase(phraseId);
CLuaIHM::pushReflectableOnStack(*ls, _PhraseAdapter);
ls->pushGlobalTable();
ls->pushGlobalTable();
CLuaObject game(*ls);
game = game["game"];
game = game["game"];
game.callMethodByNameNoThrow("updatePhraseTooltip", 1, 1);
// retrieve result from stack
help = ucstring();
@ -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
@ -576,12 +595,14 @@ public:
// For auras, powers, etc. set the range of ticks during which regen occurs
void setRegenTickRange(const CTickRange &tickRange);
const CTickRange &getRegenTickRange() const { return _RegenTickRange; }
// 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,17 +812,20 @@ 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);
// setup sheet DB. _DbBranchName must be ok, and _SecondIndexInDb and _IndexInDb as well
void setupSheetDbLinks ();
// 'regen' rendering
// convert from uv coordinates in the [0, 1] x [0, 1] range to screen coords
inline void uvToScreen(float x, float y, NLMISC::CVector &screenPos, uint texSize) const;
// from an angle in the [0, 1] range, return both uv & screen coords for that angle
// from an angle in the [0, 1] range, return both uv & screen coords for that angle
// (angle is projected on the side of rectangle of the 'regen' texture)
void buildPieCorner(float angle, NLMISC::CUV &uv, NLMISC::CVector &pos, uint texSize) const;
// from a start and end angle in the [0, 1] range, build the set of uv mapped triangles necessary

@ -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;
@ -153,21 +153,6 @@ private:
TItemInfoCacheMap _ItemInfoCacheMap;
};
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;
};
// ***************************************************************************
/** This manager gives direct access to inventory slots (bag, temporary inventory, hands, and equip inventory)
* This also give access to player money

@ -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 */
Loading…
Cancel
Save