Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / dbctrl_sheet.cpp
blob614bf1d65ae41c9360c2ef6433db9c032a96dc55
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2021 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2011-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 // Copyright (C) 2012 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
7 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
8 //
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "stdpch.h"
26 #include "dbctrl_sheet.h"
27 #include "interface_manager.h"
28 #include "nel/gui/view_text.h"
29 #include "../sheet_manager.h"
30 #include "../client_sheets/entity_sheet.h"
31 #include "../client_sheets/pact_sheet.h"
32 #include "../client_sheets/mission_icon_sheet.h"
33 #include "../client_sheets/faction_sheet.h"
34 #include "game_share/skills.h"
35 #include "game_share/inventories.h"
36 #include "list_sheet_base.h"
37 #include "../string_manager_client.h"
38 #include "nel/gui/interface_options.h"
39 #include "inventory_manager.h"
40 #include "skill_manager.h"
41 #include "../user_entity.h"
42 #include "../entities.h"
43 #include "bar_manager.h"
45 #include "macrocmd_manager.h"
46 #include "../string_manager_client.h" // For GuildFlag type
47 #include "guild_manager.h" // For GuildFlag type
48 #include "sbrick_manager.h"
49 #include "sphrase_manager.h"
50 #include "../client_sheets/sphrase_sheet.h"
51 #include "nel/misc/xml_auto_ptr.h"
52 #include "nel/gui/lua_ihm.h"
53 #include "lua_ihm_ryzom.h"
54 #include "game_share/bot_chat_types.h"
56 #include "../r2/editor.h"
58 #include "nel/gui/lua_manager.h"
59 #include "nel/misc/xml_macros.h"
61 extern CSheetManager SheetMngr;
63 using namespace std;
64 using namespace NLMISC;
65 using namespace NL3D;
66 using namespace STRING_MANAGER;
68 NLMISC::CSmartPtr<CSPhraseComAdpater> CDBCtrlSheet::_PhraseAdapter;
70 CDBCtrlSheet *CDBCtrlSheet::_CurrSelection = NULL;
71 CDBCtrlSheet *CDBCtrlSheet::_CurrMenuSheet = NULL;
72 UMaterial CDBCtrlSheet::_GuildMat;
75 NLMISC::CRGBA CDBCtrlSheet::_ArmourColor[RM_COLOR::NumColors];
77 REGISTER_UI_CLASS(CDBCtrlSheet)
80 const uint64 NOTIFY_ANIM_MS_DURATION = 1000;
82 // state kept and changed by UI:SAVE:SHOW_ICON_BUFFS
83 bool CDBCtrlSheet::_ShowIconBuffs = true;
85 // ***************************************************************************
87 void CControlSheetInfoWaiter::sendRequest()
89 if (Requesting) return;
91 Requesting = true;
92 getInventory().addItemInfoWaiter(this);
95 void CControlSheetInfoWaiter::infoReceived()
97 if (!Requesting) return;
99 getInventory().removeItemInfoWaiter(this);
100 infoValidated();
101 CtrlSheet->infoReceived();
102 Requesting = false;
106 string CControlSheetInfoWaiter::infoValidated() const
108 #ifdef RYZOM_LUA_UCSTRING
109 ucstring help; // Compatibility
110 #else
111 string help;
112 #endif
113 if (CtrlSheet && !LuaMethodName.empty())
115 // delegate setup of context he help ( & window ) to lua
116 CInterfaceManager *im = CInterfaceManager::getInstance();
117 CLuaState *ls= CLuaManager::getInstance().getLuaState();
119 CLuaStackRestorer lsr(ls, 0);
121 CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)CtrlSheet);
122 ls->pushGlobalTable();
123 CLuaObject game(*ls);
124 game = game["game"];
125 game.callMethodByNameNoThrow(LuaMethodName.c_str(), 1, 1);
127 // retrieve result from stack
128 if (!ls->empty())
130 #ifdef RYZOM_LUA_UCSTRING
131 CLuaIHM::pop(*ls, help);
132 #else
133 help = ls->toString(-1);
134 ls->pop();
135 #endif
137 else
139 nlwarning(toString("Ucstring result expected when calling '%s', possible script error", LuaMethodName.c_str()).c_str());
144 #ifdef RYZOM_LUA_UCSTRING
145 return help.toUtf8();
146 #else
147 return help;
148 #endif
151 // ***************************************************************************
152 int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls)
154 CLuaIHM::pushUIOnStack(ls, dynamic_cast<CInterfaceElement *>( dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) ));
155 return 1;
158 // ***************************************************************************
159 int CDBCtrlSheet::luaGetItemInfo(CLuaState &ls)
161 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet *>(this);
162 uint32 itemSlotId = getInventory().getItemSlotId(ctrlSheet);
163 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
165 ls.newTable();
166 CLuaObject out(ls);
167 // for now all but magic
168 out.setValue("CurrentDamage", itemInfo.CurrentDamage);
169 out.setValue("MaxDamage", itemInfo.MaxDamage);
170 out.setValue("DodgeModifier", itemInfo.DodgeModifier);
171 out.setValue("ParryModifier", itemInfo.ParryModifier);
172 out.setValue("AdversaryDodgeModifier", itemInfo.AdversaryDodgeModifier);
173 out.setValue("AdversaryParryModifier", itemInfo.AdversaryParryModifier);
174 out.setValue("Hp", itemInfo.Hp);
175 out.setValue("HpMax", itemInfo.HpMax);
176 out.setValue("Range", itemInfo.Range);
177 out.setValue("HpBuff", itemInfo.HpBuff);
178 out.setValue("SapBuff", itemInfo.SapBuff);
179 out.setValue("StaBuff", itemInfo.StaBuff);
180 out.setValue("FocusBuff", itemInfo.FocusBuff);
181 out.setValue("SapLoadCurrent", itemInfo.SapLoadCurrent);
182 out.setValue("SapLoadMax", itemInfo.SapLoadMax);
183 out.setValue("ProtectionFactor", itemInfo.ProtectionFactor);
184 out.setValue("MaxSlashingProtection", itemInfo.MaxSlashingProtection);
185 out.setValue("MaxPiercingProtection", itemInfo.MaxPiercingProtection);
186 out.setValue("MaxBluntProtection", itemInfo.MaxBluntProtection);
187 out.setValue("WearEquipmentMalus", itemInfo.WearEquipmentMalus);
188 out.push();
190 return 1;
193 // ***************************************************************************
194 int CDBCtrlSheet::luaGetName(CLuaState &ls)
196 #ifdef RYZOM_LUA_UCSTRING
197 CLuaIHM::push(ls, ucstring::makeFromUtf8(getItemActualName()));
198 #else
199 ls.push(getItemActualName());
200 #endif
201 return 1;
204 // **********************************************************************************************************
205 class LuaInfoWaiter : public IItemInfoWaiter
207 public:
208 volatile bool done;
210 public:
211 virtual void infoReceived();
215 void LuaInfoWaiter::infoReceived()
217 getInventory().removeItemInfoWaiter(this);
218 this->done = true;
221 static LuaInfoWaiter luaInfoWaiter;
223 // ***************************************************************************
224 int CDBCtrlSheet::luaGetCreatorName(CLuaState &ls)
226 uint32 itemSlotId = getInventory().getItemSlotId(this);
227 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
228 string creatorName;
229 STRING_MANAGER::CStringManagerClient::instance()->getString(itemInfo.CreatorName, creatorName);
230 #ifdef RYZOM_LUA_UCSTRING
231 CLuaIHM::push(ls, ucstring::makeFromUtf8(creatorName)); // FIXME: Lua UTF-8
232 #else
233 ls.push(creatorName);
234 #endif
236 return 1;
239 // ***************************************************************************
240 int CDBCtrlSheet::luaWaitInfo(CLuaState &ls)
242 static bool sent = false;
243 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
244 uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
245 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
247 if (sent || itemInfo.versionInfo != 0)
249 ls.push((bool)(luaInfoWaiter.done));
250 if (luaInfoWaiter.done)
251 sent = false;
252 return luaInfoWaiter.done ? 1 : 0;
254 else
256 luaInfoWaiter.ItemSlotId = itemSlotId;
257 luaInfoWaiter.ItemSheet = this->getSheetId();
258 luaInfoWaiter.done = false;
259 getInventory().addItemInfoWaiter(&luaInfoWaiter);
260 sent = true;
262 return 0;
265 // ***************************************************************************
266 int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
269 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
270 uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
271 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
273 CInterfaceManager *pIM = CInterfaceManager::getInstance();
274 CSBrickManager *pBM= CSBrickManager::getInstance();
276 uint currentBrick = 0;
277 uint i;
278 for(i=0;i<itemInfo.Enchantment.Bricks.size();i++)
280 //if ( ! (pBM->getBrick(itemInfo.Enchantment.Bricks[i])->isCredit() || pBM->getBrick(itemInfo.Enchantment.Bricks[i])->isParameter()))
282 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:VARIABLES:CRYSTALBRICKS:%d:SHEET", currentBrick++));
283 if(node)
284 node->setValue32(itemInfo.Enchantment.Bricks[i].asInt());
289 // Reset other to 0.
290 for(;;currentBrick++)
292 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:VARIABLES:CRYSTALBRICKS:%d:SHEET", currentBrick), false);
293 if(node)
294 node->setValue32(0);
295 else
296 break;
298 return 1;
302 // ***************************************************************************
304 // ----------------------------------------------------------------------------
305 CCtrlSheetInfo::CCtrlSheetInfo()
307 _Type = CCtrlSheetInfo::SheetType_Item;
308 _DispNoSheetBmpId = -1;
309 _InterfaceColor= true;
310 _SheetSelectionGroup = -1;
311 _UseQuality = true;
312 _UseQuantity = true;
313 _DuplicateOnDrag = false;
314 _ItemSlot= SLOTTYPE::UNDEFINED;
315 _AutoGrayed= false;
316 _HasTradeSlotType = false;
317 _BrickOverable= false;
318 _ReadQuantityFromSheet = false;
319 _AHOnLeftClick = NULL;
320 _AHOnRightClick = NULL;
321 _AHOnCanDrag = NULL;
322 _AHOnDrag = NULL;
323 _AHOnCanDrop = NULL;
324 _AHOnDrop = NULL;
325 _AHOnCannotDrop = NULL;
326 _DragCopy= false;
327 _ForceItemBackGroundGeneric= false;
330 void CDBCtrlSheet::release ()
332 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
333 if (Driver)
334 Driver->deleteMaterial(_GuildMat);
336 // release now the phrase or it ll be release too late and crash
337 _PhraseAdapter = 0;
340 // ----------------------------------------------------------------------------
341 bool CCtrlSheetInfo::parseCtrlInfo(xmlNodePtr cur, CInterfaceGroup * /* parentGroup */)
343 CXMLAutoPtr prop;
345 // read type
346 prop = (char*) xmlGetProp( cur, (xmlChar*)"nature" );
347 if (prop)
349 std::string lwrProp = NLMISC::toLower(prop.str());
350 if (lwrProp == "item")
351 _Type = CCtrlSheetInfo::SheetType_Item;
352 else if (lwrProp == "pact")
353 _Type = CCtrlSheetInfo::SheetType_Pact;
354 else if (lwrProp == "skill")
355 _Type = CCtrlSheetInfo::SheetType_Skill;
356 else if (lwrProp == "auto")
357 _Type = CCtrlSheetInfo::SheetType_Auto;
358 else if (lwrProp == "macro")
359 _Type = CCtrlSheetInfo::SheetType_Macro;
360 else if (lwrProp == "guild_flag")
361 _Type = CCtrlSheetInfo::SheetType_GuildFlag;
362 else if (lwrProp == "mission")
363 _Type = CCtrlSheetInfo::SheetType_Mission;
364 else if (lwrProp == "sbrick")
365 _Type = CCtrlSheetInfo::SheetType_SBrick;
366 else if (lwrProp == "sphraseid")
367 _Type = CCtrlSheetInfo::SheetType_SPhraseId;
368 else if (lwrProp == "sphrase")
369 _Type = CCtrlSheetInfo::SheetType_SPhrase;
370 else if (lwrProp == "elevator_destination")
371 _Type = CCtrlSheetInfo::SheetType_ElevatorDestination;
372 else if (lwrProp == "outpost_building")
373 _Type = CCtrlSheetInfo::SheetType_OutpostBuilding;
376 // Read bitmap
377 prop = (char*) xmlGetProp( cur, (xmlChar*)"tx_noitem" );
378 if (prop)
380 string TxName = toLowerAscii((const char *) prop);
381 CViewRenderer &rVR = *CViewRenderer::getInstance();
382 _DispNoSheetBmpId = rVR.getTextureIdFromName (TxName);
385 prop = (char*) xmlGetProp( cur, (xmlChar*)"col_noitem" );
386 if (prop)
387 _InterfaceColor = CInterfaceElement::convertBool(prop);
389 prop = (char*) xmlGetProp( cur, (xmlChar*)"use_slot_type_db_entry" );
390 if (prop)
391 _HasTradeSlotType= CInterfaceElement::convertBool(prop);
393 // Read Action handlers
394 CAHManager::getInstance()->parseAH(cur, "onclick_l", "params_l", _AHOnLeftClick, _AHLeftClickParams);
395 CAHManager::getInstance()->parseAH(cur, "onclick_r", "params_r", _AHOnRightClick, _AHRightClickParams);
396 CAHManager::getInstance()->parseAH(cur, "oncandrop", "params_candrop", _AHOnCanDrop, _AHCanDropParams);
397 CAHManager::getInstance()->parseAH(cur, "ondrop", "params_drop", _AHOnDrop, _AHDropParams);
398 CAHManager::getInstance()->parseAH(cur, "oncannotdrop", "params_cannotdrop", _AHOnCannotDrop, _AHCannotDropParams);
399 CAHManager::getInstance()->parseAH(cur, "oncandrag", "params_candrag", _AHOnCanDrag, _AHCanDragParams);
400 CAHManager::getInstance()->parseAH(cur, "ondrag", "params_drag", _AHOnDrag, _AHDragParams);
402 prop = (char*) xmlGetProp( cur, (xmlChar*)"selection_group" );
403 if (prop)
405 const CCtrlSheetSelection &css = CWidgetManager::getInstance()->getParser()->getCtrlSheetSelection();
406 _SheetSelectionGroup = css.getGroupIndex((const char *) prop);
407 if (_SheetSelectionGroup == -1)
409 nlwarning("<CCtrlSheetInfo::parseCtrlInfo> %s if not a sheet selection group", (const char *) prop);
412 else _SheetSelectionGroup = -1;
413 prop = (char*) xmlGetProp( cur, (xmlChar*)"use_quantity" );
414 if (prop) _UseQuantity = CInterfaceElement::convertBool(prop);
415 prop = (char*) xmlGetProp( cur, (xmlChar*)"read_quantity_from_sheet" );
416 if (prop) _ReadQuantityFromSheet = CInterfaceElement::convertBool(prop);
417 prop = (char*) xmlGetProp( cur, (xmlChar*)"use_quality" );
418 if (prop) _UseQuality = CInterfaceElement::convertBool(prop);
419 prop = (char*) xmlGetProp( cur, (xmlChar*)"duplicate_on_drag" );
420 if (prop) _DuplicateOnDrag = CInterfaceElement::convertBool(prop);
422 // Context menu association
423 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_l" );
424 if (prop)
426 _ListMenuLeft = toLowerAscii((const char *) prop);
428 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r" );
429 if (prop)
431 _ListMenuRight = toLowerAscii((const char *) prop);
433 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_r_empty_slot" );
434 if (prop)
436 _ListMenuRightEmptySlot = toLowerAscii((const char *) prop);
438 // list menu on both clicks
439 prop = (char*) xmlGetProp( cur, (xmlChar*)"menu_b" );
440 if (prop)
442 setListMenuBoth(toLowerAscii((const char *) prop));
445 // _BrickTypeBitField
446 prop = (char*) xmlGetProp( cur, (xmlChar*)"brick_type" );
447 if(prop)
449 // Defined => filter none.
450 _BrickTypeBitField= 0;
452 // The string may have multiple brick type separated by |
453 string brickTypeArray= (const char*)prop;
454 vector<string> strList;
455 NLMISC::splitString(NLMISC::toUpperAscii(brickTypeArray), "|", strList);
457 // Test All words
458 for(uint i=0;i<strList.size();i++)
460 BRICK_TYPE::EBrickType brickType= BRICK_TYPE::toBrickType(strList[i]);
461 if (brickType==BRICK_TYPE::UNKNOWN)
463 nlwarning("<CCtrlSheetInfo::parseCtrlInfo> %s has an unvalid Brick Type", (const char *) prop);
465 else
467 // must not have so much brick type else must change code!
468 // nlassert(brickType<32);
470 // Ok set the bit associated
471 _BrickTypeBitField|= 1<<brickType;
476 // _SlotType
477 prop = (char*) xmlGetProp( cur, (xmlChar*)"item_slot" );
478 if(prop)
480 string str= prop.str();
481 _ItemSlot= SLOTTYPE::stringToSlotType(NLMISC::toUpperAscii(str));
484 // _AutoGrayed
485 prop = (char*) xmlGetProp( cur, (xmlChar*)"auto_grayed" );
486 if(prop) _AutoGrayed= CInterfaceElement::convertBool(prop);
488 // _BrickOverable
489 prop = (char*) xmlGetProp( cur, (xmlChar*)"brick_over" );
490 if(prop) _BrickOverable= CInterfaceElement::convertBool(prop);
492 // Drag Copy support?
493 prop = (char*) xmlGetProp( cur, (xmlChar*)"drag_copy" );
494 if(prop) _DragCopy= CInterfaceElement::convertBool(prop);
496 // _ForceItemBackGroundGeneric
497 prop = (char*) xmlGetProp( cur, (xmlChar*)"force_item_background_generic" );
498 if(prop) _ForceItemBackGroundGeneric= CInterfaceElement::convertBool(prop);
500 return true;
504 // ***************************************************************************
506 NLMISC_REGISTER_OBJECT(CViewBase, CDBCtrlSheet, std::string, "sheet");
508 // ----------------------------------------------------------------------------
509 CDBCtrlSheet::CDBCtrlSheet(const TCtorParam &param) :
510 CCtrlDraggable(param)
512 _LastSheetId = 0;
513 _LastItemInfoVersion = 0;
514 _LastItemCreateTime = 0;
515 _LastItemSerial = 0;
516 _DispSlotBmpId= -1;
517 _DispBackBmpId = -1;
518 _DispSheetBmpId = -1;
519 _DispOverBmpId = -1;
520 _DispOver2BmpId= -1;
521 _CanDrop = false;
522 _Stackable= 1;
523 _DispQuality= -1;
524 _DispQuantity= -1;
525 _Over = false;
526 _TextureIdOver= -1;
527 _IndexInDB= 0;
528 _SecondIndexInDB= 0;
529 _ShortCut= false;
530 _SheetColor= CRGBA::White;
531 _OtherHandItemFilter= NULL;
532 _ActualType = _Type;
533 _ItemWeared= false;
534 _ItemBeastGrayed= false;
535 _Grayed= false;
536 _Useable= true;
537 _GrayedLink= NULL;
538 _NeedSetup= true;
539 _ItemInfoChanged = true;
540 _IconW = 0;
541 _IconH = 0;
542 _SetupInit= false;
543 _IconBackColor= CRGBA::White;
544 _IconColor= CRGBA::White;
545 _IconOverColor= CRGBA::White;
546 _IconOver2Color= CRGBA::White;
547 _PackedArmourColor= 0;
548 _MacroID = -1;
549 _GuildBack = _GuildSymb = NULL;
550 _UseGuildIcon = false;
551 _GuildIcon = NLMISC::CSheetId::Unknown;
552 _DrawSlot= true;
553 _ItemCaracReqType= CHARACTERISTICS::Unknown;
554 _ItemCaracReqValue= 0;
555 _ArmourColorFromDB= false;
556 _ArmourColorBmpOk= false;
557 _ArmourColorIndex= 0;
558 _UserColor= NULL;
559 _ItemSheet = NULL;
560 _ItemRMClassType= NULL;
561 _ItemRMFaberStatType= NULL;
562 _NotifyAnimEndTime = 0;
564 _HpBuffIcon = "ico_heal.tga";
565 _SapBuffIcon = "ico_sap.tga";
566 _StaBuffIcon = "ico_stamina.tga";
567 _FocusBuffIcon = "ico_focus.tga";
569 _RegenText = NULL;
570 _RegenTextValue = 0;
571 _RegenTextEnabled = true;
572 _RegenTextShadow = true;
573 _RegenTextOutline = false;
574 _RegenTextFctLua = false;
575 _RegenTextY = 2;
576 _RegenTextFontSize = 8;
577 _RegenTextColor = NLMISC::CRGBA::White;
578 _RegenTextShadowColor = NLMISC::CRGBA::Black;
579 _RegenTextOutlineColor = NLMISC::CRGBA::Black;
582 // ----------------------------------------------------------------------------
583 CDBCtrlSheet::~CDBCtrlSheet()
585 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
587 if (_ItemInfoWaiter.Requesting)
589 getInventory().removeItemInfoWaiter(&_ItemInfoWaiter);
592 if (_GuildBack)
594 if (Driver)
595 Driver->deleteTextureFile(_GuildBack);
596 _GuildBack = NULL;
598 if (_GuildSymb)
600 if (Driver)
601 Driver->deleteTextureFile(_GuildSymb);
602 _GuildSymb = NULL;
604 if (_RegenText)
606 delete _RegenText;
607 _RegenText = NULL;
610 // ensure erase static
611 if(this==_CurrMenuSheet) _CurrMenuSheet = NULL;
612 if(this == dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) )
613 setDraggedSheet( NULL );
614 if(this==_CurrSelection) _CurrSelection = NULL;
617 // ----------------------------------------------------------------------------
618 bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
620 CXMLAutoPtr prop;
622 if (! CCtrlBase::parse(cur,parentGroup) )
624 string tmp = "cannot parse view:"+getId()+", parent:"+parentGroup->getId();
625 nlinfo(tmp.c_str());
626 return false;
629 // parse the common ctrl info
630 if(!parseCtrlInfo(cur, parentGroup))
631 return false;
633 prop = (char*) xmlGetProp( cur, (xmlChar*)"dragable" );
634 if (prop)
635 setDraggable( CInterfaceElement::convertBool(prop) );
636 else
637 setDraggable( false );
639 if (_Type != SheetType_Macro)
641 prop = (char*) xmlGetProp( cur, (xmlChar*)"value" );
642 if (prop)
643 initSheet (string((const char*)prop), *this);
644 else
646 string tmp = "cannot get property value, view:"+getId()+", parent:"+parentGroup->getId();
647 nlinfo(tmp.c_str());
648 return false;
652 if( _Type == SheetType_SBrick || _Type == SheetType_SPhraseId || _Type == SheetType_SPhrase || _Type == SheetType_Macro )
654 prop = (char*) xmlGetProp( cur, (xmlChar*)"is_shortcut" );
655 if (prop) _ShortCut= convertBool(prop);
658 // _OtherHandItemFilter
659 prop= (char*) xmlGetProp( cur, (xmlChar*)"other_hand_slot" );
660 if(prop)
662 _OptString= (const char*)prop;
663 // Fill the Pointer in setupInit() at first updateCoords() call...
666 // _Grayed
667 prop = (char*) xmlGetProp( cur, (xmlChar*)"grayed" );
668 if(prop) _Grayed= CInterfaceElement::convertBool(prop);
670 // Draw the slot ?
671 _DrawSlot = true;
672 prop = (char*) xmlGetProp( cur, (xmlChar*)"slot" );
673 if(prop) _DrawSlot= CInterfaceElement::convertBool(prop);
676 _HpBuffIcon = "ico_heal.tga";
677 prop = (char*) xmlGetProp( cur, (xmlChar*)"hp_buff_icon" );
678 if (prop) _HpBuffIcon = string((const char *)prop);
680 _SapBuffIcon = "ico_sap.tga";
681 prop = (char*) xmlGetProp( cur, (xmlChar*)"sap_buff_icon" );
682 if (prop) _SapBuffIcon = string((const char *)prop);
684 _StaBuffIcon = "ico_stamina.tga";
685 prop = (char*) xmlGetProp( cur, (xmlChar*)"sta_buff_icon" );
686 if (prop) _StaBuffIcon = string((const char *)prop);
688 _FocusBuffIcon = "ico_focus.tga";
689 prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
690 if (prop) _FocusBuffIcon = string((const char *)prop);
692 XML_READ_BOOL(cur, "regen_text", _RegenTextEnabled, true);
693 XML_READ_BOOL(cur, "regen_text_shadow", _RegenTextShadow, true);
694 XML_READ_BOOL(cur, "regen_text_outline", _RegenTextOutline, false);
695 XML_READ_SINT(cur, "regen_text_y", _RegenTextY, 2);
696 XML_READ_UINT(cur, "regen_text_fontsize", _RegenTextFontSize, 8);
697 XML_READ_COLOR(cur, "regen_text_color", _RegenTextColor, NLMISC::CRGBA::White);
698 XML_READ_COLOR(cur, "regen_text_shadow_color", _RegenTextShadowColor, NLMISC::CRGBA::Black);
699 XML_READ_COLOR(cur, "regen_text_outline_color", _RegenTextOutlineColor, NLMISC::CRGBA::Black);
700 XML_READ_STRING(cur, "regen_text_fct", _RegenTextFct, "");
701 _RegenTextFctLua = startsWith(_RegenTextFct, "lua:");
703 updateActualType();
704 // Init size for Type
705 initSheetSize();
706 return true;
709 // ----------------------------------------------------------------------------
710 void CDBCtrlSheet::initSheet(const std::string &dbBranchId, const CCtrlSheetInfo &ctrlInfo)
712 H_AUTO ( RZ_CDBCtrlSheet_initSheet )
714 nlassert((ctrlInfo._Type == SheetType_Macro) || !dbBranchId.empty());
715 nlassert((ctrlInfo._Type == SheetType_Macro) || !_Id.empty());
717 // init
718 *static_cast<CCtrlSheetInfo*>(this)= ctrlInfo;
720 // link to the branch
721 if (ctrlInfo._Type != SheetType_Macro)
723 setSheet(dbBranchId);
725 // get over for spell
726 CInterfaceManager *pIM = CInterfaceManager::getInstance();
727 _TextureIdOver = CViewRenderer::getInstance()->getTextureIdFromName ("w_slot_spell_over.tga");
730 // Init size.
731 initSheetSize();
734 // ----------------------------------------------------------------------------
735 void CDBCtrlSheet::initSheetFast( const std::string &dbParentBranchId, int sheetNum, int slotNum,
736 const CCtrlSheetInfo &ctrlInfo )
738 H_AUTO ( RZ_CDBCtrlSheet_initSheetFast )
740 nlassert((ctrlInfo._Type == SheetType_Macro) || (!dbParentBranchId.empty()));
741 nlassert((ctrlInfo._Type == SheetType_Macro) || (!_Id.empty()));
743 // init
744 *static_cast<CCtrlSheetInfo*>(this)= ctrlInfo;
746 // link to the branch
747 if (ctrlInfo._Type != SheetType_Macro)
749 setSheetFast( dbParentBranchId, sheetNum, slotNum );
751 // get over for spell
752 CInterfaceManager *pIM = CInterfaceManager::getInstance();
753 _TextureIdOver = CViewRenderer::getInstance()->getTextureIdFromName ("w_slot_spell_over.tga");
756 // Init size.
757 initSheetSize();
760 // ----------------------------------------------------------------------------
761 std::string CDBCtrlSheet::getSheet() const
763 return _DbBranchName;
767 // ***************************************************************************
768 void CDBCtrlSheet::setSheet (const std::string &dbBranchId)
770 // link to the DBBranch
771 _DbBranchName= dbBranchId;
773 // Compute the index in DB
774 _IndexInDB= 0;
775 _SecondIndexInDB= 0;
776 string::size_type pos= dbBranchId.rfind(':');
777 if(pos!=string::npos)
779 // get the number after the ':'
780 fromString(dbBranchId.substr(pos+1), _IndexInDB);
781 // try to get the _SecondIndexInDB.
782 if(pos>0)
784 _SecondIndexInDB= getInventorySlot(dbBranchId);
788 // set sheet DB links
789 setupSheetDbLinks();
793 // ***************************************************************************
794 void CDBCtrlSheet::setSheetFast( const std::string &dbParentBranchId, int sheetNum, int slotNum )
796 H_AUTO ( RZ_CDBCtrlSheet_setSheet )
798 // link to the DBBranch
799 _DbBranchName = dbParentBranchId + ":" + NLMISC::toString(sheetNum);
801 // Set the index in DB.
802 _IndexInDB = sheetNum;
803 _SecondIndexInDB = slotNum;
805 // set sheet DB links
806 setupSheetDbLinks();
810 // ***************************************************************************
811 void CDBCtrlSheet::setupSheetDbLinks ()
813 H_AUTO ( RZ_CDBCtrlSheet_setSheet )
815 CInterfaceManager *pIM= CInterfaceManager::getInstance();
817 // link to the DBBranch (NB: none for macros)
818 CCDBNodeBranch *dbBranch = NLGUI::CDBManager::getInstance()->getDbBranch( _DbBranchName );
819 //nlassert(dbBranch || _DbBranchName.empty());
821 // link if possible with the database, else dummy link to the interface
822 switch( _Type )
824 case SheetType_Mission:
826 // LastSheetId is used as last mission text (mission text which is a server string id)
827 _LastSheetId = 0;
829 // Mission icon use _SheetId -> gives the sheet that contains the name of the icon texture
830 if( !_SheetId.link( dbBranch, _DbBranchName+":ICON", pIM->_DB_UI_DUMMY_SHEET ) )
831 nlwarning ("ERROR !!! Cannot find mission icon");
833 _Quality.link( pIM->_DB_UI_DUMMY_QUALITY );
834 break;
836 case SheetType_SPhraseId:
838 _SheetId.link( dbBranch, _DbBranchName+":PHRASE", pIM->_DB_UI_DUMMY_PHRASE );
839 break;
841 case SheetType_GuildFlag:
842 case SheetType_ElevatorDestination:
844 // LastSheetId is used as last guild name (guild name which is a server string id)
845 _LastSheetId = 0;
847 // Guild name use _SheetId
848 if( !_SheetId.link( dbBranch, _DbBranchName+":NAME", pIM->_DB_UI_DUMMY_SHEET ) )
849 nlwarning ("ERROR !!! Cannot find guild name : %s", (_DbBranchName+":NAME").c_str());
851 // Guild icon use _Quality
852 if( !_Quality.link( dbBranch, _DbBranchName+":ICON", pIM->_DB_UI_DUMMY_QUALITY ) )
853 nlwarning ("ERROR !!! Cannot find guild icon: %s", (_DbBranchName+":ICON").c_str());
855 // MacroID is used as the last guild icon
856 _MacroID = 0;
857 break;
859 default:
861 // sheet
862 _SheetId.link( dbBranch, _DbBranchName+":SHEET", pIM->_DB_UI_DUMMY_SHEET );
864 if (_HasTradeSlotType)
865 _TradeSlotType.link( dbBranch, _DbBranchName+":SLOT_TYPE", pIM->_DB_UI_DUMMY_SLOT_TYPE );
867 updateActualType();
869 if(_ActualType == SheetType_Item || _ActualType == SheetType_Pact)
871 // quality
872 if (_UseQuality)
873 _Quality.link( dbBranch, _DbBranchName+":QUALITY", pIM->_DB_UI_DUMMY_QUALITY );
874 else
875 _Quality.link(pIM->_DB_UI_DUMMY_QUALITY);
877 // quantity
878 if(_ActualType == SheetType_Item)
880 if (_UseQuantity)
881 _Quantity.link( dbBranch, _DbBranchName+":QUANTITY", pIM->_DB_UI_DUMMY_QUANTITY );
882 else
883 _Quantity.link( pIM->_DB_UI_DUMMY_QUANTITY );
885 else if(_ActualType == SheetType_Pact)
886 _UseQuantity = false;
888 // Misc Item
889 if(_ActualType == SheetType_Item)
891 // Link to worned state if possible
892 _Worned.link( dbBranch, _DbBranchName+":WORNED", pIM->_DB_UI_DUMMY_WORNED );
894 // Link to _PrerequisitValid state if possible
895 _PrerequisitValid.link( dbBranch, _DbBranchName+":PREREQUISIT_VALID", pIM->_DB_UI_DUMMY_PREREQUISIT_VALID );
900 break;
902 } // switch( _Type )
904 // Link to NameId if possible (if item, else will link to UI:DUMMY:NAMEID).
905 _NameId.link( dbBranch, _DbBranchName+":NAMEID", pIM->_DB_UI_DUMMY_NAMEID );
907 // Link to Enchant if possible (if item, else will link to UI:DUMMY:ENCHANT).
908 _Enchant.link( dbBranch, _DbBranchName+":ENCHANT", pIM->_DB_UI_DUMMY_ENCHANT );
910 if(dbBranch)
912 // Link to UserColor if possible. else will link NULL.
913 _UserColor = dbBranch->getLeaf( _DbBranchName+":USER_COLOR", false );
915 // Link to item RM types if possible, else will link NULL
916 _ItemRMClassType= dbBranch->getLeaf( _DbBranchName+":RM_CLASS_TYPE", false );
917 _ItemRMFaberStatType= dbBranch->getLeaf( _DbBranchName+":RM_FABER_STAT_TYPE", false );
919 // If auto grayed, link to "LOCKED" if possible
920 if(_AutoGrayed)
921 _GrayedLink= dbBranch->getLeaf( _DbBranchName+":LOCKED", false );
922 else
923 _GrayedLink= NULL;
925 else
927 _UserColor= NULL;
928 _ItemRMClassType= NULL;
929 _ItemRMFaberStatType= NULL;
930 _GrayedLink= NULL;
933 // force reset of cache
934 _NeedSetup= true;
938 // ***************************************************************************
939 // determine the inventory slot from the database branch id
940 // return 0 if no match found
941 uint CDBCtrlSheet::getInventorySlot( const string &dbBranchId )
943 // skip the SERVER: or LOCAL:
944 string::size_type pos = dbBranchId.find( ":" );
945 if(pos==string::npos)
946 return 0;
947 const char *szName = dbBranchId.c_str() + pos+1;
948 const char *szName2;
950 // fast selection according to first letters
951 switch( szName[0] )
953 case 'E':
954 if( strncmp( "EXCHANGE:", szName, 9 ) )
955 break;
956 szName2 = &szName[9];
957 if( !strncmp( "GIVE", szName2, 4 ) )
958 return INVENTORIES::exchange;
959 if( !strncmp( "RECEIVE", szName2, 7 ) )
960 return INVENTORIES::exchange_proposition;
961 break;
962 case 'G':
963 if( !strncmp( "GUILD:INVENTORY", szName, 15 ) )
964 return INVENTORIES::guild;
965 break;
966 case 'I':
967 if( strncmp( "INVENTORY:", szName, 10 ) )
968 break;
969 szName2 = &szName[10];
970 switch( szName2[0] )
972 case 'B':
973 if( !strncmp( "BAG", szName2, 3 ) )
974 return INVENTORIES::bag;
975 break;
976 case 'P':
977 nlctassert(MAX_INVENTORY_ANIMAL==7);
978 if( strncmp( "PACK_ANIMAL", szName2, 11 ) )
979 break;
980 switch( szName2[11] )
982 case '0':
983 return INVENTORIES::pet_animal1;
984 case '1':
985 return INVENTORIES::pet_animal2;
986 case '2':
987 return INVENTORIES::pet_animal3;
988 case '3':
989 return INVENTORIES::pet_animal4;
990 case '4':
991 return INVENTORIES::pet_animal5;
992 case '5':
993 return INVENTORIES::pet_animal6;
994 case '6':
995 return INVENTORIES::pet_animal7;
996 default:
997 break;
999 break;
1000 case 'R':
1001 if( !strncmp( "ROOM", szName2, 4 ) )
1002 return INVENTORIES::player_room;
1003 break;
1004 case 'T':
1005 if( !strncmp( "TEMP", szName2, 4 ) )
1006 return INVENTORIES::temporary;
1007 break;
1008 default:
1009 break;
1011 default:
1012 break;
1014 return 0;
1017 // ----------------------------------------------------------------------------
1018 void CDBCtrlSheet::initSheetSize()
1020 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1021 CViewRenderer &rVR = *CViewRenderer::getInstance();
1022 // If the user type is auto, then select always item slot.
1023 if(_Type==SheetType_Auto)
1025 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_item.tga");
1026 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_item_selected.tga");
1028 // Else select from actual type.
1029 else
1031 switch(_ActualType)
1033 case SheetType_Item:
1034 case SheetType_Pact:
1035 case SheetType_Mission:
1036 case SheetType_OutpostBuilding:
1037 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_item.tga");
1038 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_item_selected.tga");
1039 break;
1040 case SheetType_Macro:
1041 case SheetType_SBrick:
1042 case SheetType_SPhraseId:
1043 case SheetType_SPhrase:
1044 if(_BrickOverable)
1046 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_spell.tga");
1047 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_spell_selected.tga");
1049 else
1051 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_brick.tga");
1052 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_brick_selected.tga");
1054 break;
1055 case SheetType_ElevatorDestination:
1056 case SheetType_GuildFlag:
1057 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_blason.tga");
1058 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_blason_over.tga");
1059 break;
1060 default:
1061 break;
1064 rVR.getTextureSizeFromId (_DispSlotBmpId, _W, _H);
1067 // ----------------------------------------------------------------------------
1068 void CDBCtrlSheet::updateCoords ()
1070 if (getActive())
1072 if (_Type != CCtrlSheetInfo::SheetType_Macro)
1074 if (!_SetupInit) setupInit();
1076 if (_LastSheetId != _SheetId.getSInt32())
1078 updateActualType();
1082 switch(_ActualType)
1084 case CCtrlSheetInfo::SheetType_Item: setupItem(); break;
1085 case CCtrlSheetInfo::SheetType_Pact: setupPact(); break;
1086 case CCtrlSheetInfo::SheetType_SBrick: setupSBrick(); break;
1087 case CCtrlSheetInfo::SheetType_SPhraseId: setupSPhraseId(); break;
1088 case CCtrlSheetInfo::SheetType_SPhrase: setupSPhrase(); break;
1089 case CCtrlSheetInfo::SheetType_Mission: setupMission(); break;
1090 case CCtrlSheetInfo::SheetType_OutpostBuilding: setupOutpostBuilding(); break;
1091 default: break;
1094 if (_Type != CCtrlSheetInfo::SheetType_Macro)
1096 _LastSheetId = _SheetId.getSInt32();
1099 CInterfaceElement::updateCoords();
1102 // ----------------------------------------------------------------------------
1103 void CDBCtrlSheet::updateIconSize()
1105 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1106 CViewRenderer &rVR = *CViewRenderer::getInstance();
1107 if (_DispSheetBmpId != -1)
1109 rVR.getTextureSizeFromId(_DispSheetBmpId, _IconW, _IconH);
1111 else if (_DispBackBmpId != -1)
1113 rVR.getTextureSizeFromId(_DispBackBmpId, _IconW, _IconH);
1115 else if (_DispOverBmpId != -1)
1117 rVR.getTextureSizeFromId(_DispOverBmpId, _IconW, _IconH);
1119 else if (_DispOver2BmpId != -1)
1121 rVR.getTextureSizeFromId(_DispOver2BmpId, _IconW, _IconH);
1123 else
1125 _IconW = _IconH = 0;
1129 // ***************************************************************************
1130 void CDBCtrlSheet::clearIconBuffs()
1132 _EnchantIcons.clear();
1133 _BuffIcons.clear();
1134 _BoostIcons.clear();
1137 // ***************************************************************************
1138 void CDBCtrlSheet::infoReceived()
1140 updateIconBuffs();
1142 _LastItemInfoVersion = getItemInfoVersion();
1145 // ***************************************************************************
1146 void CDBCtrlSheet::updateIconBuffs()
1148 if (!_ItemSheet)
1150 clearIconBuffs();
1151 return;
1154 const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
1155 if (itemInfo == NULL)
1157 // schedule for recheck on next draw()
1158 _ItemInfoChanged = true;
1159 return;
1162 clearIconBuffs();
1164 // crystallized spell
1166 CViewRenderer &rVR = *CViewRenderer::getInstance();
1167 CSBrickManager *pBM= CSBrickManager::getInstance();
1168 bool haveRoot = false;
1169 for(uint i=0; i<itemInfo->Enchantment.Bricks.size(); ++i)
1171 const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
1172 if (brick)
1174 if (brick->BrickFamily == BRICK_FAMILIES::BSGMCB) // Boost of Allegories, use it as boost icon
1176 _BoostIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
1177 rVR.getTextureSizeFromId(_BoostIcons.back().TextureId, _BoostIcons.back().IconW, _BoostIcons.back().IconH);
1179 else if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
1181 if (!haveRoot)
1183 haveRoot = true;
1184 if (brick->getIconBack().empty())
1186 // use blank texture with size from main icon
1187 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName("blank.tga"), NLMISC::CRGBA::White));
1188 rVR.getTextureSizeFromId(rVR.getTextureIdFromName(brick->getIcon()), _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1190 else
1192 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
1193 rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1196 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
1197 rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1199 else if (brick->isRoot())
1201 haveRoot = true;
1202 // there should be single root icon and it should be first one
1203 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
1204 rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1210 // buff icons
1212 CViewRenderer &rVR = *CViewRenderer::getInstance();
1214 if (itemInfo->HpBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_HpBuffIcon)));
1215 if (itemInfo->SapBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_SapBuffIcon)));
1216 if (itemInfo->StaBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_StaBuffIcon)));
1217 if (itemInfo->FocusBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_FocusBuffIcon)));
1219 // update sizes
1220 for(uint i = 0; i < _BuffIcons.size(); ++i)
1222 rVR.getTextureSizeFromId(_BuffIcons[i].TextureId, _BuffIcons[i].IconW, _BuffIcons[i].IconH);
1226 _LastItemInfoVersion = getItemInfoVersion();
1229 // ***************************************************************************
1230 void CDBCtrlSheet::setupPact()
1232 sint32 sheet = _SheetId.getSInt32();
1233 // If this is the same sheet, need to resetup
1234 if (_LastSheetId != sheet || _NeedSetup)
1236 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1237 CViewRenderer &rVR = *CViewRenderer::getInstance();
1239 _LastSheetId = sheet;
1240 CSheetId sheetId(sheet);
1241 CEntitySheet *pES = SheetMngr.get (sheetId);
1242 if ((pES != NULL) && (pES->type() == CEntitySheet::PACT))
1244 CPactSheet *pPS = (CPactSheet*)pES;
1245 _DispSheetBmpId = rVR.getTextureIdFromName (pPS->Icon);
1246 _DispBackBmpId = rVR.getTextureIdFromName (pPS->IconBackground);
1247 _DispOverBmpId = -1;
1248 _DispOver2BmpId = -1;
1249 updateIconSize();
1250 if (_UseQuality)
1251 _DispQuality = _Quality.getSInt32();
1252 else
1253 _DispQuality = -1;
1255 else
1257 resetAllTexIDs();
1260 else
1262 // update quality
1263 if(_UseQuality)
1264 _DispQuality = _Quality.getSInt32();
1265 else
1266 _DispQuality = -1;
1270 // ***************************************************************************
1271 bool CDBCtrlSheet::useItemInfoForFamily(ITEMFAMILY::EItemFamily family) const
1273 return family == ITEMFAMILY::CRYSTALLIZED_SPELL
1274 || family == ITEMFAMILY::JEWELRY
1275 || family == ITEMFAMILY::ARMOR
1276 || family == ITEMFAMILY::MELEE_WEAPON
1277 || family == ITEMFAMILY::RANGE_WEAPON
1278 || family == ITEMFAMILY::SHIELD
1279 || family == ITEMFAMILY::CRAFTING_TOOL
1280 || family == ITEMFAMILY::HARVEST_TOOL
1281 || family == ITEMFAMILY::TAMING_TOOL
1282 || family == ITEMFAMILY::TRAINING_TOOL;
1285 // ***************************************************************************
1286 void CDBCtrlSheet::setupItem ()
1288 CInterfaceManager *pIM= CInterfaceManager::getInstance();
1290 sint32 sheet = _SheetId.getSInt32();
1291 sint32 itemCreateTime = getItemCreateTime();
1292 sint32 itemSerial = getItemSerial();
1294 bool isItemChanged = _LastSheetId != sheet || _LastItemCreateTime != itemCreateTime || _LastItemSerial != itemSerial;
1296 _DispQuality = -1;
1297 _DispQuantity = -1;
1299 // If this is the same sheet, need to resetup
1300 if (isItemChanged || _NeedSetup)
1302 CViewRenderer &rVR = *CViewRenderer::getInstance();
1304 _NeedSetup= false;
1305 _LastSheetId = sheet;
1306 _LastItemCreateTime = itemCreateTime;
1307 _LastItemSerial = itemSerial;
1309 CSheetId sheetId(sheet);
1310 CEntitySheet *pES = SheetMngr.get (sheetId);
1311 if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM))
1313 _ItemSheet = (CItemSheet*)pES;
1315 _DispSheetBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconMain());
1316 // if file not found or empty, replace by default icon
1317 if( _DispSheetBmpId == -1)
1318 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1319 if(_ForceItemBackGroundGeneric)
1320 _DispBackBmpId = rVR.getTextureIdFromName ("BK_generic.tga");
1321 else
1322 _DispBackBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconBack());
1323 _DispOverBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconOver());
1324 _DispOver2BmpId = rVR.getTextureIdFromName (_ItemSheet->getIconOver2());
1325 _PackedArmourColor = 0;
1326 _ArmourColorFromDB= false;
1327 _ArmourColorBmpOk= false;
1328 // if icon is an armour, and no over texture is given, build its name
1329 if (_ItemSheet->Family == ITEMFAMILY::ARMOR)
1331 sint col = _ItemSheet->Color;
1332 if (col == -1) // user color wanted ?
1334 col = getItemColor(); // read color from db
1335 // If the DB exist
1336 if(_UserColor)
1337 _ArmourColorFromDB= true;
1339 updateArmourColor(col);
1342 updateIconSize();
1344 // Icon Colors
1345 _IconBackColor= _ItemSheet->IconBackColor;
1346 _IconColor= _ItemSheet->IconColor;
1347 _IconOverColor= _ItemSheet->IconOverColor;
1348 _IconOver2Color= _ItemSheet->IconOver2Color;
1350 // Setup Quantity
1351 if (_UseQuantity)
1353 // is this item stackable? more than one.
1354 _Stackable= _ItemSheet->Stackable;
1356 if (getStackable() > 1)
1358 if (_ReadQuantityFromSheet)
1360 _DispQuantity = getStackable();
1362 else
1364 // display the stack quantity
1365 _DispQuantity = _Quantity.getSInt32();
1370 // Setup quality
1371 if(_UseQuality)
1372 _DispQuality= _Quality.getSInt32();
1374 // special icon text
1375 if( _NeedSetup || _ItemSheet->getIconText() != _OptString )
1377 // compute from OptString. Allow only 1 line (-2 for padding)
1378 _OptString= _ItemSheet->getIconText();
1379 // Display Top Left
1380 setupCharBitmaps(40-2, 1, true);
1383 // Special Item requirement
1384 updateItemCharacRequirement(_LastSheetId);
1386 // update icon buffs using cached info
1387 updateIconBuffs();
1389 // update item info markers
1390 _ItemInfoChanged = true;
1392 else
1394 resetAllTexIDs();
1397 // must update dispNumber for good quantity/quality.
1398 else
1400 // update quantity
1401 if (getStackable() > 1)
1403 if (_ReadQuantityFromSheet)
1405 _DispQuantity = getStackable();
1407 else
1409 _DispQuantity = _Quantity.getSInt32();
1413 // update quality. NB: if quality change, the must updateItemCharacRequirement
1414 if(_UseQuality)
1416 sint32 newQuality= _Quality.getSInt32();
1417 if(newQuality!=_DispQuality)
1419 _DispQuality= newQuality;
1420 updateItemCharacRequirement(_LastSheetId);
1424 // update armour color (if USER_COLOR db change comes after SHEET change)
1425 if(_ArmourColorFromDB && _UserColor)
1427 // If the DB has changed
1428 if(_UserColor->getValue32() != _ArmourColorIndex)
1430 updateArmourColor((sint8)_UserColor->getValue32());
1435 if (_ItemSheet != NULL)
1437 switch(_ItemSheet->Family)
1439 case ITEMFAMILY::ARMOR:
1440 case ITEMFAMILY::MELEE_WEAPON:
1441 case ITEMFAMILY::RANGE_WEAPON:
1442 case ITEMFAMILY::SHIELD:
1443 case ITEMFAMILY::JEWELRY:
1444 case ITEMFAMILY::CRAFTING_TOOL:
1445 case ITEMFAMILY::HARVEST_TOOL:
1446 case ITEMFAMILY::TAMING_TOOL:
1447 case ITEMFAMILY::TRAINING_TOOL:
1448 // hide 'x0' and 'x1' stack count for equipable items
1449 if (_DispQuantity < 2)
1450 _DispQuantity = -1;
1451 break;
1452 default:
1453 // hide 'q0'and 'q1' quality for every other item
1454 if (_DispQuality < 2)
1455 _DispQuality = -1;
1456 break;
1460 // at each frame, must test for grayed.
1461 if(_AutoGrayed)
1463 if(_GrayedLink)
1465 // gray if not 0
1466 _Grayed= _GrayedLink->getValue32()!=0;
1468 else
1469 _Grayed= false;
1472 // at each frame, must test for Redifyed (player carac does not met item requirement)
1473 _Useable = _PrerequisitValid.getBool();
1475 _Useable= pIM->isItemCaracRequirementMet(_ItemCaracReqType, _ItemCaracReqValue);
1477 if (_Useable && _ItemSheet != NULL)
1479 if (_ItemSheet->RequiredCharac != CHARACTERISTICS::Unknown && _ItemSheet->RequiredCharacLevel>0)
1480 _Useable= pIM->isItemCaracRequirementMet(_ItemSheet->RequiredCharac, _ItemSheet->RequiredCharacLevel);
1482 if (_Useable && _ItemSheet->RequiredSkill != SKILLS::unknown && _ItemSheet->RequiredSkillLevel > 0)
1483 _Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
1487 // at each frame, update item info icon if changed
1488 // This will not trigger on slots where client has not asked info version yet
1489 // (enchanting weapon right after login)
1490 if (_ItemInfoChanged || _LastItemInfoVersion != getItemInfoVersion())
1492 _ItemInfoChanged = false;
1493 setupItemInfoWaiter();
1498 // ***************************************************************************
1499 void CDBCtrlSheet::updateItemCharacRequirement(sint32 sheet)
1501 CSheetId sheetId(sheet);
1502 CEntitySheet *pES = SheetMngr.get (sheetId);
1503 if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM) && _Quality.getNodePtr())
1505 CItemSheet *pIS = (CItemSheet*)pES;
1506 _ItemCaracReqType= CHARACTERISTICS::Unknown;
1507 _ItemCaracReqValue= 0;
1508 float tmpVal;
1509 if(pIS->hasCharacRequirement(_Quality.getSInt32(), _ItemCaracReqType, tmpVal))
1510 _ItemCaracReqValue= (sint32)floor(tmpVal);
1515 // ***************************************************************************
1516 void CDBCtrlSheet::setupMacro()
1518 if (!_NeedSetup) return;
1520 // compute from OptString (-2 for padding)
1521 setupCharBitmaps(26-2, 4);
1523 _NeedSetup = false;
1528 // ***************************************************************************
1529 void CDBCtrlSheet::setupMission()
1531 sint32 currIcon = _SheetId.getSInt32();
1532 if (_LastSheetId != currIcon || _NeedSetup)
1534 _LastSheetId = currIcon;
1535 _NeedSetup = false;
1537 CEntitySheet *pES = SheetMngr.get(CSheetId(currIcon));
1538 if (pES == NULL) return;
1539 if (pES->Type != CEntitySheet::MISSION_ICON) return;
1540 CMissionIconSheet *pMIS = (CMissionIconSheet*)pES;
1542 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1543 CViewRenderer &rVR = *CViewRenderer::getInstance();
1545 _DispBackBmpId = rVR.getTextureIdFromName(pMIS->MainIconBg);
1546 _DispSheetBmpId = rVR.getTextureIdFromName(pMIS->MainIconFg);
1548 // Display a '?' only if not 0.
1549 if ((_DispBackBmpId == -1) && (currIcon != 0))
1551 _DispBackBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1556 // ***************************************************************************
1557 void CDBCtrlSheet::setupGuildFlag ()
1559 // Find the guild name
1560 string usGuildName;
1561 sint32 nGuildName = _SheetId.getSInt32();
1562 if (_LastSheetId != nGuildName || _NeedSetup)
1564 CStringManagerClient *pSMC = CStringManagerClient::instance();
1565 bool bValid = pSMC->getDynString (nGuildName, usGuildName);
1566 if (bValid)
1567 _NeedSetup = false;
1570 uint64 nGuildIcon;
1571 nGuildIcon = _Quality.getSInt64();
1574 _UseGuildIcon = ((nGuildIcon>>59)&1)!=0; // 1 bits en pos 59
1575 if (_UseGuildIcon)
1577 _GuildIcon = (uint32)(nGuildIcon&0xffffffff); // 32 bits en pos 0
1579 else
1581 sint8 nGuildBack = (sint8)(nGuildIcon&15); // 4 bits en pos 0
1582 sint8 nGuildSymbol = (sint8)((nGuildIcon>>4)&63); // 6 bits en pos 4
1583 sint8 nGuildInvert = (sint8)((nGuildIcon>>10)&1); // 1 bit en pos 10
1584 uint8 nGuildColBackR = (uint8)((nGuildIcon>>11)&255); // 8 bits en pos 11
1585 uint8 nGuildColBackG = (uint8)((nGuildIcon>>19)&255); // 8 bits en pos 19
1586 uint8 nGuildColBackB = (uint8)((nGuildIcon>>27)&255); // 8 bits en pos 27
1587 uint8 nGuildColSymbR = (uint8)((nGuildIcon>>35)&255); // 8 bits en pos 35
1588 uint8 nGuildColSymbG = (uint8)((nGuildIcon>>43)&255); // 8 bits en pos 43
1589 uint8 nGuildColSymbB = (uint8)((nGuildIcon>>51)&255); // 8 bits en pos 51
1591 sint8 nLastGuildBack = (sint8)(_MacroID&15); // 4 bits en pos 0
1592 sint8 nLastGuildSymbol = (sint8)((_MacroID>>4)&63); // 6 bits en pos 4
1594 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
1596 if (_GuildMat.empty())
1598 _GuildMat = Driver->createMaterial();
1599 _GuildMat.initUnlit ();
1601 // Alpha blend must use current alpha
1602 _GuildMat.setBlend (true);
1603 _GuildMat.setBlendFunc (UMaterial::one, UMaterial::invsrcalpha);
1605 // Stages 0
1606 _GuildMat.texEnvOpRGB (0, UMaterial::Modulate);
1607 _GuildMat.texEnvArg0RGB (0, UMaterial::Texture, UMaterial::SrcColor);
1608 _GuildMat.texEnvArg1RGB (0, UMaterial::Diffuse, UMaterial::SrcColor);
1609 _GuildMat.texEnvOpAlpha (0, UMaterial::Modulate);
1610 _GuildMat.texEnvArg0Alpha (0, UMaterial::Texture, UMaterial::SrcAlpha);
1611 _GuildMat.texEnvArg1Alpha (0, UMaterial::Diffuse, UMaterial::SrcAlpha);
1613 // This is alpha material, so don't zwrite
1614 _GuildMat.setZWrite (false);
1615 _GuildMat.setBlendFunc (UMaterial::srcalpha, UMaterial::invsrcalpha);
1618 if (nGuildInvert == 0)
1620 // Stages 1
1621 _GuildMat.texEnvOpRGB (1, UMaterial::Modulate);
1622 _GuildMat.texEnvArg0RGB (1, UMaterial::Texture, UMaterial::SrcColor);
1623 _GuildMat.texEnvArg1RGB (1, UMaterial::Previous, UMaterial::SrcColor);
1625 else
1627 // Stages 1
1628 _GuildMat.texEnvOpRGB (1, UMaterial::Add);
1629 _GuildMat.texEnvArg0RGB (1, UMaterial::Texture, UMaterial::InvSrcColor);
1630 _GuildMat.texEnvArg1RGB (1, UMaterial::Previous, UMaterial::SrcColor);
1634 _SheetColor = CRGBA(nGuildColBackR,nGuildColBackG,nGuildColBackB);
1635 _IconColor = CRGBA(nGuildColSymbR,nGuildColSymbG,nGuildColSymbB);
1637 if (nLastGuildBack != nGuildBack)
1639 if (_GuildBack != NULL)
1640 Driver->deleteTextureFile(_GuildBack);
1641 _GuildBack = NULL;
1642 if (nGuildBack > 0)
1644 string txName = toString("Guild_Back_S_%02d.tga", nGuildBack-1);
1645 _GuildBack = Driver->createTextureFile (txName);
1649 if (nLastGuildSymbol != nGuildSymbol)
1651 if (_GuildSymb != NULL)
1652 Driver->deleteTextureFile(_GuildSymb);
1653 _GuildSymb = NULL;
1654 if (nGuildSymbol > 0)
1656 string txName = toString("Guild_Symbol_S_%02d.tga", nGuildSymbol-1);
1657 _GuildSymb = Driver->createTextureFile (txName);
1660 _GuildMat.setTexture(0, _GuildBack);
1661 _GuildMat.setTexture(1, _GuildSymb);
1663 _MacroID = (sint32)(nGuildIcon&1023); // on garde les 10 premiers bits
1668 // ***************************************************************************
1669 void CDBCtrlSheet::setupDisplayAsSBrick(sint32 sheet, sint32 optSheet, bool force)
1671 // Setup with the param sheet
1672 CSBrickManager *pBM = CSBrickManager::getInstance();
1673 CViewRenderer &rVR = *CViewRenderer::getInstance();
1675 CSBrickSheet *pBR = pBM->getBrick (CSheetId(sheet));
1676 CSBrickSheet *pBROpt = pBM->getBrick (CSheetId(optSheet));
1677 if (pBR != NULL)
1679 // Get Back and Over.
1680 _DispBackBmpId = rVR.getTextureIdFromName (pBR->getIconBack());
1681 _IconBackColor = pBR->IconBackColor;
1682 _DispOverBmpId = rVR.getTextureIdFromName (pBR->getIconOver());
1683 _IconOverColor = pBR->IconOverColor;
1685 // For phrase display, replace icon and over2 with optional brick
1686 if (pBROpt && force)
1688 // force all icons from optSheet except background
1689 _DispSheetBmpId = rVR.getTextureIdFromName(pBROpt->getIcon());
1690 _DispOverBmpId = rVR.getTextureIdFromName(pBROpt->getIconOver());
1691 _DispOver2BmpId = rVR.getTextureIdFromName(pBROpt->getIconOver2());
1692 _IconColor = pBROpt->IconColor;
1693 _IconOverColor = pBROpt->IconOverColor;
1694 _IconOver2Color = pBROpt->IconOver2Color;
1696 else if(pBROpt)
1698 // get the correct icon
1699 bool iconOver2NotSuitableForActionDisplay;
1700 if ( pBM->getSabrinaCom().isMainDisplayIconInOverSlot( CSheetId(optSheet), iconOver2NotSuitableForActionDisplay ) )
1702 _DispSheetBmpId = rVR.getTextureIdFromName (pBROpt->getIconOver());
1703 _IconColor = pBROpt->IconOverColor;
1705 else
1707 _DispSheetBmpId = rVR.getTextureIdFromName (pBROpt->getIcon());
1708 _IconColor = pBROpt->IconColor;
1711 // get the correct over2
1712 if ( iconOver2NotSuitableForActionDisplay )
1714 _DispOver2BmpId = rVR.getTextureIdFromName (pBR->getIconOver2());
1715 _IconOver2Color = pBR->IconOver2Color;
1717 else
1719 _DispOver2BmpId = rVR.getTextureIdFromName (pBROpt->getIconOver2());
1720 _IconOver2Color = pBROpt->IconOver2Color;
1723 else
1725 _DispSheetBmpId = rVR.getTextureIdFromName (pBR->getIcon());
1726 _IconColor = pBR->IconColor;
1727 _DispOver2BmpId = rVR.getTextureIdFromName (pBR->getIconOver2());
1728 _IconOver2Color = pBR->IconOver2Color;
1731 // if file not found or empty, replace by default icon
1732 if( _DispSheetBmpId == -1)
1733 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultBrickTexture);
1734 updateIconSize();
1735 _DispLevel = pBR->Level;
1736 _MustDisplayLevel = pBR->mustDisplayLevel();
1738 else
1740 resetAllTexIDs();
1744 // ***************************************************************************
1745 void CDBCtrlSheet::setupSBrick ()
1747 sint32 sheet = (sint32)_SheetId.getSInt32();
1749 // If this is the same sheet id so no need to resetup
1750 if (_LastSheetId != sheet || _NeedSetup)
1752 _LastSheetId = sheet;
1753 setupDisplayAsSBrick(sheet);
1755 // Reseted.
1756 _NeedSetup= false;
1759 // SBrick support auto grayed. test each frame
1760 if(_AutoGrayed)
1762 if(_GrayedLink)
1764 // gray if not 0
1765 _Grayed= _GrayedLink->getValue32()!=0;
1766 // Reded, if 2
1767 _Useable= _GrayedLink->getValue32()!=2;
1769 else
1770 _Grayed= false;
1774 // ***************************************************************************
1775 void CDBCtrlSheet::setupDisplayAsPhrase(const std::vector<NLMISC::CSheetId> &bricks, const string &phraseName, uint8 phraseIconIndex)
1777 CSBrickManager *pBM = CSBrickManager::getInstance();
1779 // Get the best SBrick to display.
1780 CSheetId rootBrickSheetId= bricks[0];
1782 bool forceIcon = phraseIconIndex < bricks.size();
1783 CSheetId bestBrickSheetId = forceIcon ? bricks[phraseIconIndex] : pBM->getSabrinaCom().getPhraseBestDisplayBrick(bricks);
1784 setupDisplayAsSBrick (rootBrickSheetId.asInt(), bestBrickSheetId.asInt(), forceIcon );
1787 // Override background if type is forace extraction/prospection and ecosystem brick is used
1789 BRICK_FAMILIES::TBrickFamily family = pBM->getSabrinaCom().getPhraseForageFamily(bricks);
1790 std::string icon;
1791 switch(family)
1793 case BRICK_FAMILIES::BHFEMA:
1794 case BRICK_FAMILIES::BHFPMA:
1795 icon = "bk_matis_brick.tga";
1796 break;
1797 case BRICK_FAMILIES::BHFEMB:
1798 case BRICK_FAMILIES::BHFPMB:
1799 icon = "bk_fyros_brick.tga";
1800 break;
1801 case BRICK_FAMILIES::BHFEMC:
1802 case BRICK_FAMILIES::BHFPMC:
1803 icon = "bk_zorai_brick.tga";
1804 break;
1805 case BRICK_FAMILIES::BHFEMD:
1806 case BRICK_FAMILIES::BHFPMD:
1807 icon = "bk_tryker_brick.tga";
1808 break;
1809 case BRICK_FAMILIES::BHFEME:
1810 case BRICK_FAMILIES::BHFPME:
1811 icon = "bk_generic_brick.tga";
1812 break;
1813 default:
1814 icon = "";
1815 break;
1817 if (!icon.empty())
1819 CViewRenderer &rVR = *CViewRenderer::getInstance();
1820 _DispBackBmpId = rVR.getTextureIdFromName(icon);
1824 // not so beautiful to display .sphrase name in progression, and in botchat
1825 if(_ActualType==SheetType_SPhraseId)
1827 // Compute the text from the phrase only if needed
1828 // string iconName= phraseName.toString();
1829 const string &iconName = phraseName;
1830 if( _NeedSetup || iconName != _OptString )
1832 // recompute text
1833 _OptString= iconName;
1834 // compute from OptString. Allow only 1 line (-2 for padding)
1835 setupCharBitmaps(26-2, 1);
1840 // ***************************************************************************
1841 void CDBCtrlSheet::setupSPhrase()
1843 sint32 sheet = (sint32)_SheetId.getSInt32();
1845 // If this is the same sheet id so no need to resetup
1846 if (_LastSheetId != sheet || _NeedSetup)
1848 _LastSheetId = sheet;
1849 CSPhraseSheet *pSPS = dynamic_cast<CSPhraseSheet*>(SheetMngr.get(CSheetId(sheet)));
1850 if (pSPS && !pSPS->Bricks.empty())
1852 const char *phraseName = STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(CSheetId(sheet));
1853 setupDisplayAsPhrase(pSPS->Bricks, phraseName);
1855 else
1857 resetAllTexIDs();
1860 // Reseted.
1861 _NeedSetup= false;
1864 // SPhrase support auto grayed. test each frame
1865 if(_AutoGrayed)
1867 if(_GrayedLink)
1869 // gray if not 0
1870 _Grayed= _GrayedLink->getValue32()!=0;
1871 // Reded, if 2
1872 _Useable= _GrayedLink->getValue32()!=2;
1874 else
1875 _Grayed= false;
1879 // ***************************************************************************
1880 void CDBCtrlSheet::setupSPhraseId ()
1882 // get the phrase id
1883 sint32 phraseId = getSPhraseId();
1885 // get the phrase Data version, to check if it had changed.
1886 CSPhraseManager *pPM= CSPhraseManager::getInstance();
1887 sint32 phraseVersion= pPM->getPhraseVersion(phraseId);
1889 // If this is the same phrase id and phrase version no need to resetup
1890 if (_NeedSetup || _LastSheetId != phraseId || _LastPhraseVersion!= phraseVersion)
1892 _LastSheetId= phraseId;
1893 _LastPhraseVersion= phraseVersion;
1895 // Empty Slot?
1896 if(phraseId==0)
1898 resetAllTexIDs();
1900 else
1902 // Get the SPhrase.
1903 const CSPhraseCom &phrase= pPM->getPhrase(phraseId);
1904 if(phrase.empty())
1906 resetAllTexIDs();
1908 else
1910 setupDisplayAsPhrase(phrase.Bricks, phrase.Name.toUtf8(), phrase.IconIndex); // FIXME: UTF-8 (serial)
1914 // Reseted.
1915 _NeedSetup= false;
1919 // ***************************************************************************
1920 void CDBCtrlSheet::setupOutpostBuilding()
1922 CInterfaceManager *pIM= CInterfaceManager::getInstance();
1924 sint32 sheet = _SheetId.getSInt32();
1925 // If this is the same sheet, need to resetup
1926 if (_LastSheetId != sheet || _NeedSetup)
1928 CViewRenderer &rVR = *CViewRenderer::getInstance();
1930 _NeedSetup= false;
1931 _LastSheetId = sheet;
1932 CSheetId sheetId(sheet);
1933 CEntitySheet *pES = SheetMngr.get (sheetId);
1934 if ((pES != NULL) && (pES->type() == CEntitySheet::OUTPOST_BUILDING))
1936 COutpostBuildingSheet *pOBSheet = (COutpostBuildingSheet*)pES;
1938 _DispSheetBmpId = rVR.getTextureIdFromName (pOBSheet->getIconMain());
1939 // if file not found or empty, replace by default icon
1940 if( _DispSheetBmpId == -1)
1941 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1942 if(_ForceItemBackGroundGeneric)
1943 _DispBackBmpId = rVR.getTextureIdFromName ("BK_generic.tga");
1944 else
1945 _DispBackBmpId = rVR.getTextureIdFromName (pOBSheet->getIconBack());
1946 _DispOverBmpId = rVR.getTextureIdFromName (pOBSheet->getIconOver());
1947 _DispOver2BmpId = -1;
1948 _PackedArmourColor = 0;
1949 _ArmourColorFromDB= false;
1950 _ArmourColorBmpOk= false;
1951 updateIconSize();
1953 _DispQuantity = -1;
1954 _DispQuality = -1;
1956 // special icon text
1957 if (pOBSheet->getIconText() != _OptString)
1959 // compute from OptString. Allow only 1 line, (-2 for padding)
1960 _OptString= pOBSheet->getIconText();
1961 // Display Top Left
1962 setupCharBitmaps(40-2, 1, true);
1965 else
1967 resetAllTexIDs();
1970 // must update dispNumber for good quantity/quality.
1971 else
1973 _DispQuality = -1;
1976 // at each frame, must test for grayed.
1977 if(_AutoGrayed)
1979 if(_GrayedLink)
1981 // gray if not 0
1982 _Grayed= _GrayedLink->getValue32()!=0;
1984 else
1985 _Grayed= false;
1989 // ***************************************************************************
1990 sint32 CDBCtrlSheet::getSPhraseId() const
1992 if(_SheetId.getNodePtr())
1993 return (sint32)_SheetId.getSInt32();
1994 else
1995 return 0;
1998 // ***************************************************************************
1999 void CDBCtrlSheet::resetCharBitmaps()
2001 _CharBitmaps.clear();
2004 // ***************************************************************************
2005 void CDBCtrlSheet::setupCharBitmaps(sint32 maxW, sint32 maxLine, bool topDown)
2007 _CharBitmaps.clear();
2008 if(maxLine<=0) return;
2010 std::string text(_OptString);
2011 // check for icon text 'uiitLabel'
2012 if (text.size() > 4 && text[0] == 'u' && text[1] == 'i' && text[2] == 'i' && text[3] == 't' && CI18N::hasTranslation(text))
2014 // NOTE: translated text is expected to be us-ascii only
2015 text = CI18N::get(text);
2017 text = toLowerAscii(text);
2019 CViewRenderer &rVR = *CViewRenderer::getInstance();
2021 uint h = rVR.getTypoTextureH('a');
2022 sint lineNb = 0;
2023 sint curLineSize = 0;
2024 uint i;
2025 uint xChar= 0;
2026 for (i = 0; i < text.size(); ++i)
2028 char c = text[i];
2029 sint32 w = rVR.getTypoTextureW(c);
2030 if ((curLineSize + w) > maxW)
2032 lineNb ++;
2033 if (lineNb == maxLine) break;
2034 curLineSize = 0;
2035 xChar = 0;
2037 sint32 id = rVR.getTypoTextureId(c);
2038 if (id != -1)
2040 CCharBitmap bmp;
2041 bmp.X= curLineSize;
2042 bmp.Y= lineNb;
2043 bmp.Id= id;
2044 _CharBitmaps.push_back(bmp);
2046 curLineSize += w;
2047 ++xChar;
2050 if (lineNb == maxLine) lineNb = maxLine-1;
2052 for (i = 0; i < _CharBitmaps.size(); ++i)
2054 _CharBitmaps[i].Y = (lineNb - _CharBitmaps[i].Y)*h;
2057 // if topDown, revert Y
2058 if (topDown)
2060 for (i = 0; i < _CharBitmaps.size(); ++i)
2062 _CharBitmaps[i].Y = _IconH - _CharBitmaps[i].Y - h;
2067 // ***************************************************************************
2068 void CDBCtrlSheet::displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, CRGBA color)
2070 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2071 CViewRenderer &rVR = *CViewRenderer::getInstance();
2073 for (uint i = 0; i < _CharBitmaps.size(); ++i)
2075 rVR.draw11RotFlipBitmap (rdrLayer, x+_CharBitmaps[i].X, y+_CharBitmaps[i].Y, 0, false,
2076 _CharBitmaps[i].Id, color);
2081 // ***************************************************************************
2082 void CDBCtrlSheet::draw()
2084 H_AUTO( RZ_Interface_CDBCtrlSheet_draw )
2086 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2087 CViewRenderer &rVR = *CViewRenderer::getInstance();
2089 if (_Type != SheetType_Macro)
2091 if (_LastSheetId != _SheetId.getSInt32())
2093 updateActualType();
2094 _LastSheetId = _SheetId.getSInt32();
2095 _NeedSetup= true;
2099 // Manage over for brick
2100 if( _BrickOverable && (isMacro() || isSBrickOrSPhraseId() || isSPhrase()) )
2102 const vector<CCtrlBase*> &rVB = CWidgetManager::getInstance()->getCtrlsUnderPointer ();
2103 uint32 i;
2104 for (i = 0; i < rVB.size(); ++i)
2105 if (rVB[i] == this)
2107 _Over = true;
2108 break;
2110 if (i == rVB.size())
2111 _Over = false;
2115 // Display slot
2116 if (_DrawSlot)
2117 rVR.draw11RotFlipBitmap (_RenderLayer, _XReal, _YReal, 0, false, _DispSlotBmpId, CWidgetManager::getInstance()->getGlobalColorForContent());
2119 // Drag'N'Drop : display the selected slot bitmap if this slot accept the currently dragged element
2120 _CanDrop = false;
2121 if (_AHOnCanDrop != NULL)
2122 if ((CWidgetManager::getInstance()->getCapturePointerLeft() != NULL) && (CWidgetManager::getInstance()->getCapturePointerLeft() != this))
2124 if ((CWidgetManager::getInstance()->getPointer()->getX() >= _XReal) &&
2125 (CWidgetManager::getInstance()->getPointer()->getX() < (_XReal + _WReal))&&
2126 (CWidgetManager::getInstance()->getPointer()->getY() > _YReal) &&
2127 (CWidgetManager::getInstance()->getPointer()->getY() <= (_YReal+ _HReal)))
2128 if (CWidgetManager::getInstance()->getCurrentWindowUnder() == CWidgetManager::getInstance()->getWindow(this))
2130 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCapturePointerLeft());
2131 if ((pCSSrc != NULL) && pCSSrc->isDragged())
2133 string params = string("src=") + pCSSrc->getId();
2134 if (!_AHCanDropParams.empty())
2136 if ( CAHManager::getInstance()->getAHName(_AHOnCanDrop) == "lua")
2138 params = _AHCanDropParams;
2139 strFindReplace(params, "%src", pCSSrc->getId());
2141 else
2143 string sTmp = _AHCanDropParams;
2144 params = sTmp + "|" + params;
2147 CAHManager::getInstance()->runActionHandler (_AHOnCanDrop, this, params);
2152 drawSheet (_XReal+1, _YReal+1, isDragged() );
2154 // Draw the selection after the sheet. Important for spells because selection border is same size as spell square
2155 if (_CanDrop)
2157 // decal layer because must drawn after Items/Brick in DXTC
2158 rVR.draw11RotFlipBitmap (_RenderLayer+1, _XReal, _YReal, 0, false, _DispSelSlotId, CWidgetManager::getInstance()->getGlobalColorForContent());
2161 if (_RegenTickRange.EndTick != _RegenTickRange.StartTick)
2163 if (!_LastSheetId)
2165 _RegenTickRange = CTickRange();
2166 if (_RegenText)
2168 delete _RegenText;
2169 _RegenText = NULL;
2170 _RegenTextValue = 0;
2173 else
2175 // Render regen texture in overlay, in clock wise order
2176 float amount = (LastGameCycle - _RegenTickRange.StartTick) / float(_RegenTickRange.EndTick - _RegenTickRange.StartTick);
2177 clamp(amount, 0.f, 1.f);
2179 sint32 texWidth;
2180 sint32 texHeight;
2181 uint32 frontTex = rVR.getSystemTextureId(CViewRenderer::RegenTexture);
2182 uint32 backTex = rVR.getSystemTextureId(CViewRenderer::RegenBackTexture);
2184 rVR.getTextureSizeFromId(frontTex, texWidth, texHeight);
2185 CQuadUV regenTris[5];
2186 uint numTris = buildPie(regenTris, 0.f, amount, texWidth);
2187 nlassert(numTris <= sizeofarray(regenTris));
2188 for (uint tri = 0; tri < numTris; ++tri)
2190 rVR.drawQuad(_RenderLayer + 1, regenTris[tri], frontTex, CRGBA::White, false);
2192 numTris = buildPie(regenTris, amount, 1.f, texWidth);
2193 nlassert(numTris <= sizeofarray(regenTris));
2194 for (uint tri = 0; tri < numTris; ++tri)
2196 rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false);
2199 if (_RegenTextEnabled)
2200 drawRegenText();
2204 if (_NotifyAnimEndTime > T1)
2206 if (!_LastSheetId)
2208 _NotifyAnimEndTime = 0;
2210 else
2212 float animProgress = 1.f - float(_NotifyAnimEndTime - T1) / float(NOTIFY_ANIM_MS_DURATION);
2213 sint32 texId = rVR.getSystemTextureId(CViewRenderer::GlowStarTexture);
2214 if (texId != -1)
2216 sint32 texWidth, texHeight;
2217 rVR.getTextureSizeFromId(texId, texWidth, texHeight);
2218 const float freq0 = 1.f;
2219 const float phase0 = 0.f;
2220 const float freq1 = -1.f;
2221 const float phase1 = 0.f;
2222 float scale = sqrtf(1.f - animProgress);
2223 drawRotatedQuad(rVR, float(NLMISC::Pi) * animProgress * freq0 + phase0, scale, _RenderLayer + 3, (uint32)texId, texWidth, texHeight);
2224 drawRotatedQuad(rVR, float(NLMISC::Pi) * animProgress * freq1 + phase1, scale, _RenderLayer + 3, (uint32)texId, texWidth, texHeight);
2230 // ----------------------------------------------------------------------------
2231 void CDBCtrlSheet::drawRegenText()
2233 if (!_RegenText) {
2234 _RegenText = new CViewText(CViewBase::TCtorParam());
2235 _RegenText->setId(getId() + ":regen");
2236 _RegenText->setParent(_Parent);
2237 _RegenText->setOverflowText(std::string());
2238 _RegenText->setModulateGlobalColor(false);
2239 _RegenText->setMultiLine(true);
2240 _RegenText->setTextMode(CViewText::ClipWord);
2241 _RegenText->setFontSize(_RegenTextFontSize);
2242 _RegenText->setColor(_RegenTextColor);
2243 // do not set shadow if outline is set to avoid clearing it on draw (would call invalidate)
2244 _RegenText->setShadow(_RegenTextShadow && !_RegenTextOutline);
2245 _RegenText->setShadowOutline(false);
2246 _RegenText->setShadowColor(_RegenTextShadowColor);
2248 _RegenText->setActive(true);
2249 _RegenText->updateTextContext();
2252 // TODO: 10 hardcoded (ticks in second)
2253 sint32 nextValue;
2254 if (_RegenTickRange.EndTick > LastGameCycle)
2255 nextValue = (_RegenTickRange.EndTick - LastGameCycle) / 10;
2256 else if (_RegenTextFctLua)
2257 nextValue = ((sint64)_RegenTickRange.EndTick - (sint64)LastGameCycle) / 10;
2258 else
2259 nextValue = 0;
2261 if (_RegenTextValue != nextValue)
2263 _RegenTextValue = nextValue;
2264 if (_RegenTextFct.empty())
2266 // format as "10m", "9'59", "59"
2267 if (_RegenTextValue > 600)
2269 _RegenText->setText(toString("%dm", _RegenTextValue / 60));
2271 else if (_RegenTextValue > 0)
2273 if (_RegenTextValue < 60)
2274 _RegenText->setText(toString("%d", _RegenTextValue));
2275 else
2276 _RegenText->setText(toString("%d'%02d", _RegenTextValue / 60, _RegenTextValue % 60));
2278 else
2280 _RegenText->setText("");
2283 else
2285 std::string fct;
2286 if (_RegenTextFctLua)
2288 CCDBNodeBranch *root = getRootBranch();
2289 if (root)
2290 fct = toString("%s(%d, '%s')", _RegenTextFct.c_str(), _RegenTextValue, root->getFullName().c_str());
2291 else
2292 fct = toString("%s(%d, nil)", _RegenTextFct.c_str(), _RegenTextValue);
2294 else
2296 fct = toString("%s(%d)", _RegenTextFct.c_str(), _RegenTextValue);
2299 // if using color tags in format, then RegenText color should be set to CRGBA::White
2300 // as tag color is modulated with main color
2301 std::string result;
2302 if (CInterfaceExpr::evalAsString(fct, result))
2303 _RegenText->setTextFormatTaged(result);
2306 _RegenText->updateTextContext();
2307 // todo: posref
2308 // note: if x,y is moved outside icon area it might get cliped and not be visible (wreal/hreal == 0)
2309 _RegenText->setX(_WReal / 2 -_RegenText->getMaxUsedW() / 2);
2310 // move RegenTextY=0 to baseline
2311 _RegenText->setY(_RegenTextY - _RegenText->getFontLegHeight());
2314 _RegenText->setXReal(_XReal + _RegenText->getX());
2315 _RegenText->setYReal(_YReal + _RegenText->getY());
2316 _RegenText->setRenderLayer(_RenderLayer+2);
2318 // TODO: create shader for this
2319 if (_RegenTextOutline)
2321 // player.xml t_bonus_text template way of drawing
2322 sint x = _RegenText->getXReal();
2323 sint y = _RegenText->getYReal();
2325 _RegenText->setColor(_RegenTextShadowColor);
2326 _RegenText->setXReal(x-1); _RegenText->setYReal(y+0); _RegenText->draw();
2327 _RegenText->setXReal(x+1); _RegenText->setYReal(y+0); _RegenText->draw();
2328 _RegenText->setXReal(x+0); _RegenText->setYReal(y-1); _RegenText->draw();
2329 _RegenText->setXReal(x+0); _RegenText->setYReal(y+1); _RegenText->draw();
2331 _RegenText->setColor(_RegenTextColor);
2332 _RegenText->setXReal(x); _RegenText->setYReal(y);
2333 _RegenText->draw();
2334 _RegenText->draw();
2336 else
2338 _RegenText->draw();
2339 _RegenText->draw();
2343 // ----------------------------------------------------------------------------
2344 void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 texId, sint32 texWidth, sint32 texHeight)
2346 NLMISC::CQuadUV quv;
2347 float cosA = cosf(angle);
2348 float sinA = sinf(angle);
2350 quv.V0.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA + sinA),
2351 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA - cosA), 0.5f);
2353 quv.V1.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA + sinA),
2354 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA - cosA), 0.5f);
2356 quv.V2.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA - sinA),
2357 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA + cosA), 0.5f);
2359 quv.V3.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA - sinA),
2360 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA + cosA), 0.5f);
2362 quv.Uv0.set(0.f, 0.f);
2363 quv.Uv1.set(1.f, 0.f);
2364 quv.Uv2.set(1.f, 1.f);
2365 quv.Uv3.set(0.f, 1.f);
2367 vr.drawQuad(renderLayer, quv, texId, CRGBA::White, true);
2371 // ----------------------------------------------------------------------------
2372 inline void CDBCtrlSheet::uvToScreen(float x, float y, CVector &screenPos, uint texSize) const
2374 screenPos.set(_XReal + texSize * x, _YReal + texSize * (1.f - y), 0.5f);
2378 // ----------------------------------------------------------------------------
2379 void CDBCtrlSheet::buildPieCorner(float angle, CUV &uv, CVector &pos, uint texSize) const
2381 float radAngle = angle * 2.f * float(NLMISC::Pi);
2382 // angle origin is at 12'o'clock
2383 float x = cosf(0.5f * float(NLMISC::Pi) - radAngle);
2384 float y = sinf(0.5f * float(NLMISC::Pi) - radAngle);
2385 // project on sides
2386 if (fabsf(y) > fabsf(x))
2388 if (y > 0.f)
2390 // top
2391 x /= y;
2392 y = 1.f;
2394 else
2396 // bottom
2397 x /= -y;
2398 y = -1.f;
2401 else
2403 if (x > 0.f)
2405 y /= x;
2406 x = 1.f;
2408 else
2410 y /= -x;
2411 x = -1.f;
2414 // remap to unit quad
2415 // (well we could have worked with tan() too, I find it simpler this way ....)
2416 uv.set(0.5f * x + 0.5f, 0.5f - 0.5f * y);
2417 uvToScreen(uv.U, uv.V, pos, texSize);
2420 // ----------------------------------------------------------------------------
2421 uint CDBCtrlSheet::buildPie(CQuadUV *triPtr, float startAngle, float endAngle, uint texSize)
2423 static volatile bool exit1 = false;
2424 nlassert(startAngle <= endAngle);
2425 const sint32 factor = 65536;
2426 const float invFactor = 1.f / factor;
2427 sint32 iCurr = (uint32) (startAngle * factor) ;
2428 sint32 iEnd = (uint32) (endAngle * factor);
2429 clamp(iCurr, 0, factor);
2430 clamp(iEnd, 0, factor);
2431 uint triCount = 0;
2432 CVector quadCenter;
2433 uvToScreen(0.5f, 0.5f, quadCenter, texSize);
2435 while (iCurr != iEnd)
2437 sint32 iNext = iCurr + (factor / 4);
2438 iNext -= ((iNext - factor / 8) % (factor / 4)); // snap to nearest corner
2439 iNext = std::min(iNext, iEnd);
2440 // well, not really a quad, but we don't have yet simple triangles rendering in the ui
2441 triPtr->Uv0.set(0.5f, 0.5f);
2442 triPtr->V0 = quadCenter;
2443 buildPieCorner(iCurr * invFactor, triPtr->Uv3, triPtr->V3, texSize);
2444 buildPieCorner(iNext * invFactor, triPtr->Uv2, triPtr->V2, texSize);
2445 // turn a quad into a tri ... :/
2446 triPtr->Uv1 = triPtr->Uv0;
2447 triPtr->V1 = triPtr->V0;
2449 iCurr = iNext;
2451 ++ triPtr;
2452 ++ triCount;
2454 return triCount;
2457 // ----------------------------------------------------------------------------
2458 // Modulate only if iconColor is not White.
2459 static inline CRGBA fastMulRGB(CRGBA sheetColor, CRGBA iconColor)
2461 // NB: the test here is more to avoid loss of precision when icon value is 255,255,255
2462 if(iconColor==CRGBA::White)
2464 return sheetColor;
2466 else
2468 CRGBA ret= sheetColor; // copy alpha from sheetColor
2469 ret.modulateFromColorRGBOnly(sheetColor, iconColor);
2470 return ret;
2474 // ----------------------------------------------------------------------------
2475 void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelectionBorder /*= true*/)
2477 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2478 CViewRenderer &rVR = *CViewRenderer::getInstance();
2479 // The sheet is the slot-2
2480 sint32 wSheet= _WReal-2;
2481 sint32 hSheet= _HReal-2;
2483 // the sheet color is modulated by GlobalAlpha, but not by global RGB
2484 CRGBA curSheetColor= _SheetColor;
2485 curSheetColor.A= ( (CWidgetManager::getInstance()->getGlobalColorForContent().A+1) * _SheetColor.A )>>8;
2486 // The "disp with no sheet" case is a bit different
2487 CRGBA curNoSheetColor;
2488 if(_InterfaceColor)
2489 curNoSheetColor= CWidgetManager::getInstance()->getGlobalColorForContent();
2490 else
2491 curNoSheetColor= CRGBA(255,255,255, CWidgetManager::getInstance()->getGlobalColorForContent().A);
2493 // The gray color
2494 CRGBA grayColor= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionCtrlSheetGrayColor).getValColor();
2495 CRGBA redifyColor= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionCtrlSheetRedifyColor).getValColor();
2497 // The color of the number.
2498 CRGBA numberColor;
2499 if(!_Useable)
2501 // do not modulate color for redifyed color
2502 numberColor= redifyColor;
2503 numberColor.A= (uint8)(((uint32)redifyColor.A * (CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
2505 else if(_Grayed)
2506 numberColor.modulateFromColor(grayColor, CWidgetManager::getInstance()->getGlobalColorForContent());
2507 else
2508 numberColor= CWidgetManager::getInstance()->getGlobalColorForContent();
2510 // Different draws according to Sheet Type.
2511 switch (_ActualType)
2513 case CCtrlSheetInfo::SheetType_Pact:
2514 setupPact();
2515 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2516 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2517 if (_DispQuality != -1)
2519 // For pact sheets, the quality gives the level of the sheet
2520 drawNumber(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1);
2522 break;
2523 case CCtrlSheetInfo::SheetType_Skill:
2524 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::SkillTexture), curSheetColor);
2525 break;
2526 case CCtrlSheetInfo::SheetType_Item:
2527 setupItem();
2529 if(!_Useable)
2530 curSheetColor.modulateFromColor(redifyColor, curSheetColor);
2531 else if (_Grayed || _ItemWeared || _ItemBeastGrayed)
2532 curSheetColor.modulateFromColor(grayColor, curSheetColor);
2534 // if worned display an icon over the item's icon (a red cross for exemple)
2535 if (_Worned.getBool())
2537 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemWornedTexture), curSheetColor);
2540 // Display
2541 if ((_DispSheetBmpId == -1) || (draging && !_DuplicateOnDrag))
2543 if(_DispNoSheetBmpId!=-1)
2545 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2548 else
2550 // Background and icon
2551 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, fastMulRGB(curSheetColor, _IconBackColor));
2552 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, fastMulRGB(curSheetColor, _IconColor));
2554 // if an armour, draw colored part
2555 if (_PackedArmourColor != 0)
2557 CRGBA armourCol;
2558 armourCol.setPacked(_PackedArmourColor);
2559 armourCol.modulateFromColor(curSheetColor, armourCol);
2560 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, armourCol);
2561 // decal layer because must drawn after Items/Brick in DXTC
2562 // NB: use OverColor, not Over2Color here. Because of hack in updateArmourColor()
2563 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor));
2565 else
2567 // decal layer because must drawn after Items/Brick in DXTC
2568 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor));
2569 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
2572 if (_ShowIconBuffs && !_BuffIcons.empty())
2574 // there is max 4 icons
2575 sint32 hArea = (hSheet / 4);
2576 sint32 xIcon = x;
2577 // move buff icons up a row, quantity text is displayed on bottom-left corner
2578 sint32 yIcon = y + (_DispQuantity > 0 ? hArea : 0);
2579 for (uint i = 0; i < _BuffIcons.size(); ++i)
2581 sint32 wIcon = _BuffIcons[i].IconW;
2582 sint32 hIcon = _BuffIcons[i].IconH;
2583 if (hIcon > hArea)
2585 wIcon = wIcon * ((float)hArea / hIcon);
2586 hIcon = hArea;
2588 rVR.drawRotFlipBitmap (_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _BuffIcons[i].TextureId, fastMulRGB(curSheetColor, _BuffIcons[i].Color));
2589 xIcon += wIcon;
2590 // move up the row for 3rd/4th icon
2591 if (i % 3 == 1) {
2592 xIcon = x;
2593 yIcon += hIcon;
2598 // Is the item enchanted ?
2599 sint32 enchant = _Enchant.getSInt32();
2600 if (enchant > 0)
2602 // Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
2603 enchant--;
2604 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
2605 drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
2608 if (_ShowIconBuffs && !_EnchantIcons.empty())
2610 // draw icons in column of 3, top-right
2611 sint32 hArea = (hSheet / 3);
2612 sint32 xIcon = x + wSheet - 1;
2613 sint32 yIcon = y + hSheet - 1;
2614 sint32 yTop = yIcon;
2615 // 0 is expected to be background
2616 for (uint i = 1; i < _EnchantIcons.size(); ++i)
2618 sint32 wIcon = _EnchantIcons[i].IconW;
2619 sint32 hIcon = _EnchantIcons[i].IconH;
2620 if (hIcon > hArea)
2622 wIcon = wIcon * ((float)hArea / hIcon);
2623 hIcon = hArea;
2625 // need to move x before draw because of right aligned
2626 if (i == 1)
2628 xIcon -= wIcon;
2630 yIcon -= hIcon;
2631 rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
2632 rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
2635 if ((i - 1) < _BoostIcons.size()) {
2636 rVR.drawRotFlipBitmap(_RenderLayer + 2, xIcon+wIcon-_BoostIcons[i-1].IconW, yIcon, _BoostIcons[i-1].IconW, _BoostIcons[i-1].IconH, 0, false, _BoostIcons[i-1].TextureId, fastMulRGB(curSheetColor, _BoostIcons[i-1].Color));
2639 // move to new column as needed
2640 if (i % 3 == 0) {
2641 xIcon -= wIcon;
2642 yIcon = yTop;
2649 // Draw Quality. -1 for lookandfeel. Draw it with global color
2650 if (_DispQuality != -1)
2652 drawNumber(x-1,y+1,wSheet, hSheet, numberColor, _DispQuality);
2654 // Draw Quantity
2655 if (_UseQuantity && _DispQuantity>-1)
2657 sint32 crossId= rVR.getSystemTextureId(CViewRenderer::QuantityCrossTexture);
2658 sint32 crossW= rVR.getSystemTextureW(CViewRenderer::QuantityCrossTexture);
2659 // +1 for lookandfeel
2660 // draw the "x" bitmap. decal layer because must drawn after Items/Brick in DXTC
2661 rVR.draw11RotFlipBitmap (_RenderLayer+2, x+1, y+1, 0, false, crossId, curSheetColor);
2662 // draw the number next to it
2664 sint32 quantity = _DispQuantity;
2665 if (getLockValuePtr())
2667 quantity -= getLockValuePtr()->getValue32();
2669 drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false);
2672 // if a raw material for example, must add special icon text.
2673 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2675 // Add the lock overlay if needed
2676 if (getLockedByOwner())
2678 rVR.draw11RotFlipBitmap (_RenderLayer+1, x - 2, y + 8, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemLockedByOwnerTexture), curSheetColor);
2681 break;
2682 // Action
2683 case CCtrlSheetInfo::SheetType_Macro:
2684 setupMacro();
2685 if ( ((_DispBackBmpId == -1) && (_DispOverBmpId == -1) && (_DispOver2BmpId == -1)) ||
2686 (draging && isShortCut()) )
2688 if(_DispNoSheetBmpId != -1)
2689 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2691 else
2693 if (_DispBackBmpId != -1)
2694 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2695 if (_DispOverBmpId != -1)
2696 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, curSheetColor);
2697 if (_DispOver2BmpId != -1)
2698 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOver2BmpId, curSheetColor);
2700 // if the pointer is over the button
2701 if (_Over)
2702 // Draw -1,-1 because the slot over is 26x26
2703 rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2705 // Display Macro Text
2707 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2709 break;
2710 case CCtrlSheetInfo::SheetType_GuildFlag:
2711 setupGuildFlag();
2712 if (_UseGuildIcon)
2714 sint32 guildFlagBmpId = -1;
2715 CFactionSheet* guildIconSheet = NULL;
2716 if (_GuildIcon!=NLMISC::CSheetId::Unknown)
2717 guildIconSheet = dynamic_cast<CFactionSheet*>(SheetMngr.get(_GuildIcon));
2718 if (guildIconSheet!=NULL && !guildIconSheet->Icon.empty())
2719 guildFlagBmpId = rVR.getTextureIdFromName(guildIconSheet->Icon);
2720 // else
2721 // guildFlagBmpId = rVR.getTextureIdFromName("asc_unknown.tga");
2722 if (guildFlagBmpId != -1)
2723 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, guildFlagBmpId, curSheetColor);
2725 else if (_MacroID == 0)
2727 if(_DispNoSheetBmpId != -1)
2728 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2730 else
2732 CRGBA col;
2733 col = _SheetColor;
2734 col.modulateFromui (col, curSheetColor.A);
2735 col.A = curSheetColor.A;
2737 rVR.drawCustom (x, y, 32, 32, CUV(0,0), CUV(0.5f,1), CUV(0,0), CUV(1,1), col, _GuildMat);
2739 col= _IconColor;
2740 col.modulateFromui (col, curSheetColor.A);
2741 col.A = curSheetColor.A;
2743 rVR.drawCustom (x, y, 32, 32, CUV(0.5f,0), CUV(1,1), CUV(0,0), CUV(1,1), col, _GuildMat);
2745 // if the pointer is over the button
2746 if (_Over)
2747 // Draw -1,-1 because the slot over is 26x26
2748 rVR.draw11RotFlipBitmap (_RenderLayer+2, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2750 break;
2751 case CCtrlSheetInfo::SheetType_Mission:
2752 setupMission();
2753 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2754 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2755 break;
2756 // same drawing for sbrick and sphrase
2757 case CCtrlSheetInfo::SheetType_SBrick:
2758 case CCtrlSheetInfo::SheetType_SPhraseId:
2759 case CCtrlSheetInfo::SheetType_SPhrase:
2761 switch(_ActualType)
2763 case SheetType_SBrick : setupSBrick(); break;
2764 case SheetType_SPhraseId : setupSPhraseId(); break;
2765 case SheetType_SPhrase : setupSPhrase(); break;
2766 default: nlassert(true); break;
2770 bool showOutOfRangeSymbol = false;
2771 bool forceGrayed = false;
2773 // for phrases, display special icon if a target is selected and if it is too far
2774 if (_ActualType == CCtrlSheetInfo::SheetType_SPhraseId)
2776 sint32 phraseId = getSPhraseId();
2777 if (phraseId)
2779 CSPhraseManager *pPM= CSPhraseManager::getInstance();
2780 const CSPhraseCom &phrase= pPM->getPhrase(phraseId);
2781 // get the phrase Data version, to check if it had changed.
2782 uint32 totalActionMalus = pPM->getTotalActionMalus(phrase);
2783 uint8 targetSlot = UserEntity->targetSlot();
2784 if (targetSlot < CLFECOMMON::INVALID_SLOT)
2786 CEntityCL *target = EntitiesMngr.entity(targetSlot);
2787 if (target && UserEntity)
2789 double dist2 = (target->pos() - UserEntity->pos()).sqrnorm();
2790 CSBrickManager *pBM= CSBrickManager::getInstance();
2791 CSBrickSheet *rootBrick= NULL;
2792 if(phrase.Bricks.size())
2793 rootBrick= pBM->getBrick(phrase.Bricks[0]);
2795 if(rootBrick && rootBrick->isMagic())
2797 // offensive magic can be used against an ennemy only
2798 if(rootBrick->ActionNature == ACTNATURE::OFFENSIVE_MAGIC)
2800 forceGrayed = !target->isEnemy();
2802 else
2805 bool isPrimalMagic = false;
2806 uint i;
2807 for(i=0;i<phrase.Bricks.size();i++)
2809 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
2810 if(brick && brick->BrickFamily == BRICK_FAMILIES::BMSTEA)
2812 isPrimalMagic = true;
2813 break;
2817 if (!isPrimalMagic)
2819 forceGrayed = !(target->isPlayer() && target->isFriend());
2821 else
2823 forceGrayed = false;
2828 if (!forceGrayed)
2830 sint phraseRange;
2831 sint rangeMalus;
2832 pPM->getPhraseMagicRange(phrase, totalActionMalus, phraseRange, rangeMalus);
2833 double rangeDist = (float) (phraseRange + rangeMalus);
2834 if (phraseRange != 0) // if range is '0' then it is a 'self' action
2836 rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
2837 if (dist2 > rangeDist * rangeDist)
2839 showOutOfRangeSymbol = true;
2844 else if(rootBrick && rootBrick->isCombat())
2846 forceGrayed = target->isNeutral();
2848 else if(rootBrick && rootBrick->isSpecialPower())
2850 bool isTaunt = false;
2852 uint maxRange= 255;
2853 uint i;
2854 for(i=0;i<phrase.Bricks.size();i++)
2856 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
2857 if (brick)
2859 maxRange= min(maxRange, (uint)brick->MaxRange);
2860 if(brick->BrickFamily == BRICK_FAMILIES::BSFMA)
2863 forceGrayed = target->isNeutral();
2864 isTaunt = true;
2869 if (isTaunt && !forceGrayed)
2871 double rangeDist = (float) maxRange;
2872 rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
2873 if (dist2 > rangeDist * rangeDist)
2875 showOutOfRangeSymbol = true;
2881 // in every cases, test against current gauges to see if the action is possible
2882 if (UserEntity)
2884 sint cost;
2885 sint costMalus;
2886 CBarManager &bm = *CBarManager::getInstance();
2888 pPM->getPhraseHpCost(phrase, totalActionMalus, cost, costMalus);
2889 if (cost > bm.getUserScore(SCORES::hit_points)) forceGrayed = true;
2891 pPM->getPhraseSapCost(phrase, totalActionMalus, cost, costMalus);
2892 if (cost > bm.getUserScore(SCORES::sap)) forceGrayed = true;
2894 pPM->getPhraseStaCost(phrase, totalActionMalus, cost, costMalus);
2895 if (cost > bm.getUserScore(SCORES::stamina)) forceGrayed = true;
2897 pPM->getPhraseFocusCost(phrase, totalActionMalus, cost, costMalus);
2898 if (cost > bm.getUserScore(SCORES::focus)) forceGrayed = true;
2904 if(!_Useable)
2905 curSheetColor.modulateFromColor(redifyColor, curSheetColor);
2906 else if(_Grayed || forceGrayed)
2907 curSheetColor.modulateFromColor(grayColor, curSheetColor);
2909 // display even if draging, fut for memory: act like shortcut
2910 if (_DispSheetBmpId == -1 || (draging && isShortCut()))
2912 if(_DispNoSheetBmpId!=-1)
2914 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2917 else
2919 // center the brick (because may be in an item slot when sheetType is auto)
2920 sint32 px = x + ((_W - 2) / 2) - (BrickSheetWidth / 2);
2921 sint32 py = y + ((_H - 2) / 2) - (BrickSheetHeight / 2);
2923 // The brick must drawn in 24x24 even if bitmap is an item-like (MP knowledge bricks for example)
2924 rVR.drawRotFlipBitmap (_RenderLayer, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispBackBmpId, fastMulRGB(curSheetColor, _IconBackColor));
2925 rVR.drawRotFlipBitmap (_RenderLayer, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispSheetBmpId, fastMulRGB(curSheetColor, _IconColor));
2926 // decal layer because must drawn after Items/Brick in DXTC
2927 rVR.drawRotFlipBitmap (_RenderLayer+1, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor));
2928 rVR.drawRotFlipBitmap (_RenderLayer+1, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
2929 // Draw Quality. -1 for lookandfeel.
2930 if( _ActualType == CCtrlSheetInfo::SheetType_SBrick )
2932 if (_UseQuality && _MustDisplayLevel) drawNumber(px-1,py+1,BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel);
2934 else
2936 // Display SPhrase Icon Name
2937 displayCharBitmaps(_RenderLayer+1, x, y, curSheetColor);
2939 // if the pointer is over the button
2940 if (_Over)
2941 // Draw -1,-1 because the slot over is 26x26
2942 rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2945 if (showOutOfRangeSymbol)
2947 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::OutOfRangeTexture), CRGBA::White);
2950 break;
2951 case CCtrlSheetInfo::SheetType_OutpostBuilding:
2952 setupOutpostBuilding();
2953 if (_DispBackBmpId != -1)
2954 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2955 if (_DispSheetBmpId != -1)
2956 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2957 if (_DispOverBmpId != -1)
2958 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, curSheetColor);
2959 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2960 break;
2961 default:
2962 break;
2965 if (showSelectionBorder)
2967 if (!isDragged() || (isDragged() && _DuplicateOnDrag))
2969 // draw selection border if this sheet is selected
2970 if (_SheetSelectionGroup != -1) // is this sheet selectable ?
2971 { // yes, check if it is selected
2972 const CCtrlSheetSelection &css = CWidgetManager::getInstance()->getParser()->getCtrlSheetSelection();
2973 const CSheetSelectionGroup *ssg = css.getGroup(_SheetSelectionGroup);
2974 if (ssg)
2976 // test is the selection group is active and if this item is selected
2977 if (ssg->isActive() && _CurrSelection == this)
2979 // compute middle of the slot
2980 sint32 middleX = _XReal + (_WReal >> 1);
2981 sint32 middleY = _YReal + (_HReal >> 1);
2982 sint32 tw = ssg->getTextureWidth();
2983 sint32 th = ssg->getTextureHeight();
2984 // we are selected -> draw the selection border
2985 CRGBA color = ssg->getColor();
2986 if (ssg->isGlobalColorEnabled())
2988 color.modulateFromColor(color, CWidgetManager::getInstance()->getGlobalColorForContent());
2990 // decal layer because must drawn after Items/Brick in DXTC
2991 rVR.draw11RotFlipBitmap (_RenderLayer+1, middleX - (tw >> 1), middleY - (th >> 1), 0, false, ssg->getTextureIndex(), color);
2999 // ----------------------------------------------------------------------------
3000 sint32 CDBCtrlSheet::drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value, bool rightAlign)
3002 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3003 CViewRenderer &rVR = *CViewRenderer::getInstance();
3004 sint32 wDigit= rVR.getFigurTextureW();
3005 sint32 hDigit= rVR.getFigurTextureH();
3007 sint32 totalWidth = 0;
3009 if (value > -1)
3011 // compute start pos
3012 sint32 units = value;
3013 sint32 pos;
3014 if(rightAlign)
3015 pos= wSheet-wDigit;
3016 else
3018 // compute number of digits to display
3019 pos= 0;
3020 uint numDigits= 0;
3023 units = units / 10;
3024 numDigits++;
3026 while (units != 0);
3027 // so pos is:
3028 pos= numDigits*wDigit - wDigit;
3030 // display digits
3031 units = value;
3034 sint32 unitsID = rVR.getFigurTextureId (units % 10);
3035 // decal layer because must drawn after Items/Brick in DXTC
3036 rVR.drawRotFlipBitmap (_RenderLayer+2, x+pos, y, wDigit, hDigit, 0, false, unitsID, color);
3037 units = units / 10;
3038 pos-= wDigit;
3039 totalWidth += wDigit;
3041 while (units != 0);
3042 return totalWidth;
3044 return -1;
3047 // ----------------------------------------------------------------------------
3048 bool CDBCtrlSheet::handleEvent (const NLGUI::CEventDescriptor &event)
3050 if (CCtrlBase::handleEvent(event)) return true;
3051 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3052 if (event.getType() == NLGUI::CEventDescriptor::mouse)
3054 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
3056 // Handle drag'n'drop
3057 if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
3059 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && !isDragged())
3061 _DragX = eventDesc.getX();
3062 _DragY = eventDesc.getY();
3065 bool validClic = false;
3066 if (_DispSheetBmpId!=-1)
3068 // Cannot drag if grayed (LOCKED or LATENT)!. Still can drag a shortcut
3069 if (asItemSheet() && asItemSheet()->Stackable > 1 && _UseQuantity)
3071 validClic = isDraggable() && !isDragged() && (getQuantity() > 0);
3072 validClic = validClic && (!getItemWeared());
3074 else
3076 validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isSPhraseId());
3079 if (_Type == SheetType_Macro)
3081 validClic = isDraggable();
3084 // posssibly check AH to see if really can draging
3085 if (validClic && _AHOnCanDrag != NULL)
3087 _TempCanDrag= true;
3088 CAHManager::getInstance()->runActionHandler (_AHOnCanDrag, this, _AHCanDragParams);
3089 validClic= _TempCanDrag;
3092 if (validClic)
3094 if ((abs(_DragX-eventDesc.getX()) > 5) || (abs(_DragY-eventDesc.getY()) > 5))
3096 _DeltaDragX= _DragX-(_XReal+1);
3097 _DeltaDragY= _DragY-(_YReal+1);
3098 if (_DeltaDragX > _WReal) _DeltaDragX = _WReal;
3099 if (_DeltaDragY > _HReal) _DeltaDragY = _HReal;
3100 setDragged( true );
3101 setDraggedSheet( this );
3103 if (_AHOnDrag != NULL)
3105 CAHManager::getInstance()->runActionHandler (_AHOnDrag, this, _AHDragParams);
3110 if (isDragged())
3112 // If mouse left up, must end the Drag
3113 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
3115 bool handled = false;
3116 // get the ctrl under the drop
3117 const vector<CCtrlBase*> &rCUP = CWidgetManager::getInstance()->getCtrlsUnderPointer();
3118 CDBCtrlSheet *pCSdest = NULL;
3119 for (uint32 i = 0; i < rCUP.size(); ++i)
3121 CCtrlBase *pCB = rCUP[i];
3122 if (pCB != this)
3124 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(pCB);
3125 pCSdest = pCS;
3126 if (pCSdest != NULL)
3127 break;
3131 // if ctrl exist
3132 if (pCSdest != NULL)
3134 // dest have a drop action and have a drop request?
3135 if(pCSdest->_AHOnDrop != NULL && pCSdest->_AHOnCanDrop != NULL)
3137 // test if can drop me on dest
3138 pCSdest->_CanDrop= false;
3139 string params = string("src=") + _Id;
3140 if (!pCSdest->_AHCanDropParams.empty())
3142 if (CAHManager::getInstance()->getAHName(pCSdest->_AHOnCanDrop) == "lua")
3144 params = pCSdest->_AHCanDropParams;
3145 strFindReplace(params, "%src", _Id);
3147 else
3149 string sTmp = pCSdest->_AHCanDropParams;
3150 params = sTmp + "|" + params;
3153 CAHManager::getInstance()->runActionHandler (pCSdest->_AHOnCanDrop, pCSdest, params);
3155 // Drop only if canDrop.
3156 if(pCSdest->_CanDrop)
3158 // build params
3159 string params = string("src=") + _Id;
3160 if (!pCSdest->_AHDropParams.empty())
3162 if (CAHManager::getInstance()->getAHName(pCSdest->_AHOnDrop) == "lua")
3164 params = pCSdest->_AHDropParams;
3165 strFindReplace(params, "%src", _Id);
3167 else
3169 string sTmp = pCSdest->_AHDropParams;
3170 params = sTmp + "|" + params;// must copy 'drop' params at start because it could be the name of a procedure
3173 // call action
3174 CAHManager::getInstance()->runActionHandler (pCSdest->_AHOnDrop, pCSdest, params);
3175 handled = true;
3179 else // If slot not found try to drop on a list
3181 // get the list under the drop
3182 const vector<CInterfaceGroup*> &rGUP = CWidgetManager::getInstance()->getGroupsUnderPointer();
3183 CDBGroupListSheet *pList = NULL;
3184 CDBGroupListSheetText *pTextList = NULL;
3185 for (uint32 i = 0; i < rGUP.size(); ++i)
3187 pList = dynamic_cast<CDBGroupListSheet*>(rGUP[i]);
3188 if (pList != NULL)
3189 if (pList->getCanDrop())
3190 break;
3192 pTextList = dynamic_cast<CDBGroupListSheetText*>(rGUP[i]);
3193 if (pTextList != NULL)
3194 if (pTextList->getCanDrop())
3195 break;
3198 if ((pList != NULL) || (pTextList != NULL))
3200 if (pList != NULL)
3201 if (pList->getCtrlSheetInfo()._AHOnDrop != NULL && pList->getCtrlSheetInfo()._AHOnCanDrop != NULL)
3203 pList->setCanDrop(false);
3204 string params = string("src=") + _Id;
3205 if (!pList->getCtrlSheetInfo()._AHCanDropParams.empty())
3207 if (CAHManager::getInstance()->getAHName(pList->getCtrlSheetInfo()._AHOnCanDrop) == "lua")
3209 params = pList->getCtrlSheetInfo()._AHCanDropParams;
3210 strFindReplace(params, "%src", _Id);
3212 else
3214 string sTmp = pList->getCtrlSheetInfo()._AHCanDropParams;
3215 params = sTmp + "|" + params;
3218 CAHManager::getInstance()->runActionHandler (pList->getCtrlSheetInfo()._AHOnCanDrop, pList, params);
3220 // Drop only if canDrop.
3221 if(pList->getCanDrop())
3223 // build params
3224 string params = string("src=") + _Id;
3225 if (!pList->getCtrlSheetInfo()._AHDropParams.empty())
3227 if (CAHManager::getInstance()->getAHName(pList->getCtrlSheetInfo()._AHOnDrop) == "lua")
3229 params = pList->getCtrlSheetInfo()._AHDropParams;
3230 strFindReplace(params, "%src", _Id);
3232 else
3234 string sTmp = pList->getCtrlSheetInfo()._AHDropParams;
3235 params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure
3238 // call action
3239 CAHManager::getInstance()->runActionHandler (pList->getCtrlSheetInfo()._AHOnDrop, pList, params);
3240 handled = true;
3244 if (pTextList != NULL)
3245 if (pTextList->getCtrlSheetInfo()._AHOnDrop != NULL && pTextList->getCtrlSheetInfo()._AHOnCanDrop != NULL)
3247 pTextList->setCanDrop(false);
3248 string params = string("src=") + _Id;
3249 if (!pTextList->getCtrlSheetInfo()._AHCanDropParams.empty())
3251 string sTmp = pTextList->getCtrlSheetInfo()._AHCanDropParams;
3252 params = sTmp + "|" + params;
3254 CAHManager::getInstance()->runActionHandler (pTextList->getCtrlSheetInfo()._AHOnCanDrop, pTextList, params);
3256 // Drop only if canDrop.
3257 if(pTextList->getCanDrop())
3259 // build params
3260 string params = string("src=") + _Id;
3261 if (!pTextList->getCtrlSheetInfo()._AHDropParams.empty())
3263 string sTmp = pTextList->getCtrlSheetInfo()._AHDropParams;
3264 params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure
3266 // call action
3267 CAHManager::getInstance()->runActionHandler (pTextList->getCtrlSheetInfo()._AHOnDrop, pTextList, params);
3268 handled = true;
3275 if (!handled && _AHOnCannotDrop != NULL )
3277 CAHManager::getInstance()->runActionHandler (_AHOnCannotDrop, this, _AHCannotDropParams);
3278 handled = true;
3281 // In all case, quit
3282 setDragged( false );
3283 setDraggedSheet( NULL );
3284 // In call case, end of drag => consider handled to not call another action
3285 return true;
3290 // If we are dragging, no more event on us
3291 if(isDragged())
3292 return false; // true;
3294 // Mouse events that must be done over the control
3295 if (!((eventDesc.getX() >= _XReal) &&
3296 (eventDesc.getX() < (_XReal + _WReal))&&
3297 (eventDesc.getY() > _YReal) &&
3298 (eventDesc.getY() <= (_YReal+ _HReal))))
3299 return false;
3301 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
3303 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3304 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
3305 return false;
3307 // RunAction
3308 if(_AHOnLeftClick != NULL)
3309 CAHManager::getInstance()->runActionHandler (_AHOnLeftClick, this, _AHLeftClickParams);
3310 // Run Menu (if item is not being dragged)
3311 if (!_ListMenuLeft.empty() && dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) == NULL)
3313 if (getSheetId() != 0)
3315 _CurrMenuSheet = this;
3316 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuLeft);
3319 // Always return true on LeftClick.
3320 return true;
3323 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
3325 return true;
3328 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
3330 bool handled= false;
3331 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3332 if (CWidgetManager::getInstance()->getCapturePointerRight() != this)
3333 return false;
3335 // RunAction
3336 if(_AHOnRightClick != NULL)
3338 handled= true;
3339 CAHManager::getInstance()->runActionHandler (_AHOnRightClick, this, _AHRightClickParams);
3341 // Run Menu (if item is not being dragged)
3342 if (!_ListMenuRight.empty() || !_ListMenuRightEmptySlot.empty())
3344 handled= true;
3345 // There must be no dragged sheet
3346 if( dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) == NULL)
3348 // if a macro, don't test if Sheet==0
3349 if ( isMacro() || getSheetId() != 0)
3351 if(!_ListMenuRight.empty())
3353 _CurrMenuSheet = this;
3354 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRight);
3357 // if sheetId==0, then may open the other menu
3358 else
3360 if(!_ListMenuRightEmptySlot.empty())
3362 _CurrMenuSheet = this;
3363 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRightEmptySlot);
3368 // If not handled here, ret to parent
3369 return handled;
3373 return false;
3377 // ----------------------------------------------------------------------------
3378 CCDBNodeBranch *CDBCtrlSheet::getRootBranch() const
3380 if (_SheetId.getNodePtr())
3382 return _SheetId.getNodePtr()->getParent();
3384 return NULL;
3388 // ***************************************************************************
3389 static void swapDBProps(CCDBNodeLeaf *a, CCDBNodeLeaf *b)
3391 if(!a || !b)
3392 return;
3393 sint32 val= a->getValue32();
3394 a->setValue32(b->getValue32());
3395 b->setValue32(val);
3398 // ***************************************************************************
3399 void CDBCtrlSheet::swapSheet(CDBCtrlSheet *other)
3401 sint32 sheetId= other->_SheetId.getSInt32();
3402 other->_SheetId.setSInt32(_SheetId.getSInt32());
3403 _SheetId.setSInt32(sheetId);
3404 // For Items try to swap all other infos
3405 if(_ActualType==SheetType_Item)
3407 // quantity
3408 _Quantity.swap32(other->_Quantity);
3409 _Quality.swap32(other->_Quality);
3410 _NameId.swap32(other->_NameId);
3411 _Enchant.swap32(other->_Enchant);
3413 // swap the other props only if the DB exist in the 2 version. else no-op
3414 swapDBProps(_UserColor, other->_UserColor);
3415 swapDBProps(getItemLockedPtr(), other->getItemLockedPtr());
3416 swapDBProps(getItemWeightPtr(), other->getItemWeightPtr());
3417 swapDBProps(getItemInfoVersionPtr(), other->getItemInfoVersionPtr());
3418 swapDBProps(getItemRMClassTypePtr(), other->getItemRMClassTypePtr());
3419 swapDBProps(getItemRMFaberStatTypePtr(), other->getItemRMFaberStatTypePtr());
3420 swapDBProps(getItemPrerequisitValidPtr(), other->getItemPrerequisitValidPtr());
3421 swapDBProps(getItemSerialPtr(), other->getItemSerialPtr());
3422 swapDBProps(getItemCreateTimePtr(), other->getItemCreateTimePtr());
3426 // ***************************************************************************
3427 void CDBCtrlSheet::setCurrSelection(CDBCtrlSheet *selected)
3429 _CurrSelection = selected;
3430 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:SHEET")->setValue64(selected ? selected->getSheetId() : 0);
3431 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:QUALITY")->setValue64(selected ? selected->getQuality() : 0);
3432 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:SLOT_TYPE")->setValue64(selected ? selected->getBehaviour() : 0);
3433 // set the selection group in the db
3434 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SELECTION_GROUP")->setValue64(selected ? selected->getSelectionGroup() : -1);
3437 // ***************************************************************************
3438 const std::string &CDBCtrlSheet::getSelectionGroupAsString() const
3440 CInterfaceManager *im = CInterfaceManager::getInstance();
3441 const CCtrlSheetSelection &css = CWidgetManager::getInstance()->getParser()->getCtrlSheetSelection();
3442 const CSheetSelectionGroup *csg = css.getGroup(_SheetSelectionGroup);
3443 static const string emptyStr;
3444 return csg ? csg->getName() : emptyStr;
3447 // ***************************************************************************
3448 sint32 CDBCtrlSheet::getNonLockedQuantity() const
3450 sint32 nonLockedQt = getQuantity();
3451 CCDBNodeLeaf *lockedPtr = getItemLockedPtr();
3452 if (lockedPtr != NULL)
3453 nonLockedQt -= lockedPtr->getValue32();
3454 if (nonLockedQt < 0)
3455 nonLockedQt = 0;
3456 return nonLockedQt;
3459 // ***************************************************************************
3460 const CItemSheet *CDBCtrlSheet::asItemSheet() const
3462 updateActualType();
3463 if( _ActualType!=SheetType_Item )
3464 return NULL;
3466 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3467 if (sheet && sheet->type() == CEntitySheet::ITEM)
3469 return (CItemSheet *) sheet;
3471 return NULL;
3474 // ***************************************************************************
3475 const CPactSheet *CDBCtrlSheet::asPactSheet() const
3477 updateActualType();
3478 if( _ActualType!=SheetType_Pact )
3479 return NULL;
3481 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3482 if (sheet && sheet->type() == CEntitySheet::PACT)
3484 return (CPactSheet *) sheet;
3486 return NULL;
3489 // ***************************************************************************
3490 const CSBrickSheet *CDBCtrlSheet::asSBrickSheet() const
3492 updateActualType();
3493 if( _ActualType!=SheetType_SBrick )
3494 return NULL;
3496 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3497 if (sheet && sheet->type() == CEntitySheet::SBRICK)
3499 return (CSBrickSheet *) sheet;
3501 return NULL;
3504 // ***************************************************************************
3505 const CSPhraseSheet *CDBCtrlSheet::asSPhraseSheet() const
3507 updateActualType();
3508 if( _ActualType!=SheetType_SPhrase )
3509 return NULL;
3511 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3512 if (sheet && sheet->type() == CEntitySheet::SPHRASE)
3514 return (CSPhraseSheet *) sheet;
3516 return NULL;
3519 // ***************************************************************************
3520 const COutpostBuildingSheet *CDBCtrlSheet::asOutpostBuildingSheet() const
3522 updateActualType();
3523 if (_ActualType != SheetType_OutpostBuilding)
3524 return NULL;
3526 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3527 if (sheet && sheet->type() == CEntitySheet::OUTPOST_BUILDING)
3529 return (COutpostBuildingSheet *) sheet;
3531 return NULL;
3534 // ***************************************************************************
3535 void CDBCtrlSheet::setupItemInfoWaiter()
3537 const CItemSheet *item = asItemSheet();
3538 if(!item)
3540 clearIconBuffs();
3541 return;
3544 if (!useItemInfoForFamily(item->Family))
3546 clearIconBuffs();
3547 return;
3550 if (getItemSerial() == 0 || getItemCreateTime() == 0)
3552 clearIconBuffs();
3553 return;
3556 string luaMethodName = ((item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip");
3557 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
3558 uint itemSlotId = getInventory().getItemSlotId(ctrlSheet);
3560 // Prepare the waiter for tooltips
3561 _ItemInfoWaiter.ItemSheet= ctrlSheet->getSheetId();
3562 _ItemInfoWaiter.LuaMethodName = luaMethodName;
3563 _ItemInfoWaiter.ItemSlotId= itemSlotId;
3564 _ItemInfoWaiter.CtrlSheet = ctrlSheet;
3566 // Use cache on first load or when server updates info version.
3567 // This will show wrong info if item is in cache, but modified server side.
3568 const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
3569 sint32 itemInfoVersion = getItemInfoVersion();
3570 if (itemInfo && (_LastItemInfoVersion == 0 || itemInfoVersion == _LastItemInfoVersion))
3572 infoReceived();
3574 else
3576 // Using isInventoryPresent/Available() will fail for packers when out of range
3577 // Getting server item however will work correctly for packer/room/guild
3578 const CItemImage *itemImage = getInventory().getServerItem(itemSlotId);
3579 if (itemImage)
3581 _ItemInfoWaiter.sendRequest();
3583 else
3585 // schedule for next draw() - if inventory should not be available (ie guild),
3586 // but user opens it anyway, then this will loop back here on every draw()
3587 _ItemInfoChanged = true;
3592 // ***************************************************************************
3593 void CDBCtrlSheet::getContextHelp(std::string &help) const
3595 if (getType() == CCtrlSheetInfo::SheetType_Skill)
3597 // just show the name of the skill
3598 // the sheet id is interpreted as a skill enum
3599 help= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName( (SKILLS::ESkills)_SheetId.getSInt32() );
3601 else if(getType() == CCtrlSheetInfo::SheetType_Macro)
3603 help = _ContextHelp;
3604 const CMacroCmd *macro = CMacroCmdManager::getInstance()->getMacroFromMacroID(getMacroId());
3605 if (!macro)
3606 return;
3608 string macroName = macro->Name;
3609 if (macroName.empty())
3610 macroName = CI18N::get("uiNotAssigned");
3612 string assignedTo = macro->Combo.toString();
3613 if (assignedTo.empty())
3614 assignedTo = CI18N::get("uiNotAssigned");
3616 string dispText;
3617 string dispCommands;
3618 const CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
3620 uint nb = 0;
3621 for (uint i = 0; i < macro->Commands.size(); ++i)
3623 string commandName;
3624 for (uint j = 0; j < pMCM->ActionManagers.size(); ++j)
3626 CAction::CName c(macro->Commands[i].Name.c_str(), macro->Commands[i].Params.c_str());
3627 if (pMCM->ActionManagers[j]->getBaseAction(c) != NULL)
3629 commandName = pMCM->ActionManagers[j]->getBaseAction(c)->getActionLocalizedText(c);
3630 // display a few commands
3631 if (nb < 5)
3632 dispCommands += "\n" + commandName;
3633 ++nb;
3634 break;
3638 // formats
3639 dispText = "%n (@{6F6F}%k@{FFFF})\n%c";
3640 if (nb > 5) // more?
3641 dispCommands += toString(" ... @{6F6F}%i@{FFFF}+", nb-5);
3643 strFindReplace(dispText, "%n", macroName);
3644 strFindReplace(dispText, "%k", assignedTo);
3645 strFindReplace(dispText, "%c", dispCommands);
3646 help = dispText;
3648 else if(getType() == CCtrlSheetInfo::SheetType_Item)
3650 const CItemSheet *item= asItemSheet();
3651 if(item)
3653 if (useItemInfoForFamily(item->Family))
3655 // call lua function to update tooltip window
3656 if (!getInventory().isItemInfoUpToDate(_ItemInfoWaiter.ItemSlotId))
3657 _ItemInfoWaiter.sendRequest();
3658 help = _ItemInfoWaiter.infoValidated();
3659 // its expected to get at least item name back
3660 if (help.empty())
3661 help = getItemActualName();
3663 else
3665 help = getItemActualName();;
3668 else
3669 help= _ContextHelp;
3671 else if(getType() == CCtrlSheetInfo::SheetType_Pact)
3673 const CPactSheet *item= asPactSheet();
3674 if(item)
3676 sint32 quality = getQuality();
3677 if (quality >= (sint32) 0 && quality < (sint32) item->PactLose.size())
3679 help= item->PactLose[quality].Name;
3681 else
3683 help= _ContextHelp;
3686 else
3688 help= _ContextHelp;
3691 else if(getType() == CCtrlSheetInfo::SheetType_SBrick)
3693 CSBrickManager *pBM= CSBrickManager::getInstance();
3694 CSBrickSheet *brick= pBM->getBrick(CSheetId(getSheetId()));
3695 if(brick)
3696 help= STRING_MANAGER::CStringManagerClient::getSBrickLocalizedName(brick->Id);
3697 else
3698 help= _ContextHelp;
3700 else if(getType() == CCtrlSheetInfo::SheetType_SPhraseId)
3702 sint32 phraseId= getSheetId();
3703 if (phraseId == 0)
3705 help = std::string();
3707 else
3709 // delegate setup of context he help ( & window ) to lua
3710 CInterfaceManager *im = CInterfaceManager::getInstance();
3711 CLuaState *ls= CLuaManager::getInstance().getLuaState();
3713 CLuaStackRestorer lsr(ls, 0);
3714 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3715 _PhraseAdapter = new CSPhraseComAdpater;
3716 _PhraseAdapter->Phrase = pPM->getPhrase(phraseId);
3717 CLuaIHM::pushReflectableOnStack(*ls, _PhraseAdapter);
3718 ls->pushGlobalTable();
3719 CLuaObject game(*ls);
3720 game = game["game"];
3721 game.callMethodByNameNoThrow("updatePhraseTooltip", 1, 1);
3722 // retrieve result from stack
3723 if (!ls->empty())
3725 #ifdef RYZOM_LUA_UCSTRING
3726 ucstring tmpHelp; // Compatibility
3727 CLuaIHM::pop(*ls, tmpHelp);
3728 help = tmpHelp.toUtf8();
3729 #else
3730 help = ls->toString();
3731 ls->pop();
3732 #endif
3734 else
3736 nlwarning("Ucstring result expected when calling 'game:updatePhraseTooltip', possible script error");
3741 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3742 // The sheetId point to a phrase in the manager, get it
3743 sint32 phraseId= getSheetId();
3744 if(phraseId)
3745 help= pPM->getPhrase(phraseId).Name;
3746 else
3747 help= _ContextHelp;
3749 sint32 phraseSheetID = pPM->getSheetFromPhrase(pPM->getPhrase(phraseId));
3750 if (phraseSheetID != 0)
3752 // is it a built-in phrase?
3753 string desc = STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedDescription(NLMISC::CSheetId(phraseSheetID));
3754 if (!desc.empty())
3756 help += "\n\n@{CCCF}" + desc;
3761 else if(getType() == CCtrlSheetInfo::SheetType_SPhrase)
3763 CSPhraseSheet *phrase= dynamic_cast<CSPhraseSheet*>(SheetMngr.get(CSheetId(getSheetId())));
3764 if(phrase)
3765 help= STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(phrase->Id);
3766 else
3767 help= _ContextHelp;
3769 else if(getType() == CCtrlSheetInfo::SheetType_OutpostBuilding)
3771 const COutpostBuildingSheet *outpost = asOutpostBuildingSheet();
3772 if (outpost)
3773 help = CStringManagerClient::getOutpostBuildingLocalizedName(CSheetId(_SheetId.getSInt32()));
3774 else
3775 help = _ContextHelp;
3779 // ***************************************************************************
3780 void CDBCtrlSheet::getContextHelpToolTip(std::string &help) const
3782 // Special case for buff items and spell crystals, only for tooltips
3783 if (getType() == CCtrlSheetInfo::SheetType_Item)
3785 const CItemSheet *item = asItemSheet();
3786 if (item)
3788 if (useItemInfoForFamily(item->Family))
3790 if (!getInventory().isItemInfoUpToDate(_ItemInfoWaiter.ItemSlotId))
3791 _ItemInfoWaiter.sendRequest();
3792 help = _ItemInfoWaiter.infoValidated();
3793 return;
3798 // Default
3799 getContextHelp(help);
3802 // ***************************************************************************
3803 bool CDBCtrlSheet::canDropItem(CDBCtrlSheet *src) const
3805 if (src->getSheetId() == 0)
3806 return true;
3808 // If the dest or src is Grayed, cannot drop it
3809 if (src->getInventoryIndex() != INVENTORIES::exchange)
3811 if (src->getGrayed() || getGrayed())
3812 return false;
3813 if (src->getItemWeared() || getItemWeared())
3814 return false;
3817 // if no filter defined => OK.
3818 if (_ItemSlot == SLOTTYPE::UNDEFINED)
3819 return true;
3821 // Verify the item slot of the src
3822 CSheetId sheetId(src->getSheetId());
3823 CEntitySheet *pES = SheetMngr.get(sheetId);
3824 if (pES == NULL || pES->type() != CEntitySheet::ITEM)
3825 return false;
3827 CItemSheet *pIS = (CItemSheet *)pES;
3829 // build the bitField for test.
3830 uint32 bf;
3831 bf = 1 << _ItemSlot;
3832 // special for right hand
3833 if (_ItemSlot == SLOTTYPE::RIGHT_HAND)
3835 // Can put an object in right hand also if it is TWO_HANDS, or RIGHT_HAND_EXCLUSIVE
3836 bf |= 1 << SLOTTYPE::TWO_HANDS;
3837 bf |= 1 << SLOTTYPE::RIGHT_HAND_EXCLUSIVE;
3840 // Look if one slot solution match.
3841 if (pIS->SlotBF & bf)
3843 // Ok the object is compatible with the dest
3845 // Can put an object in left or right hand is dependent of other hand content
3846 if (_OtherHandItemFilter && _ItemSlot == SLOTTYPE::LEFT_HAND)
3848 // If the item comes from right hand cant drop
3849 if (src->_ItemSlot == SLOTTYPE::RIGHT_HAND)
3850 return false;
3851 // get the item in the right hand
3852 CSheetId sheetId(_OtherHandItemFilter->getSheetId());
3853 CEntitySheet *pRightHandES = SheetMngr.get(sheetId);
3854 // if item present: must check if the right has a TWO_HANDS or RIGHT_HAND_EXCLUSIVE
3855 if (pRightHandES != NULL && pRightHandES->type() == CEntitySheet::ITEM)
3857 CItemSheet *pRightHandIS = (CItemSheet *)pRightHandES;
3858 if (pRightHandIS->hasSlot(SLOTTYPE::TWO_HANDS) || pRightHandIS->hasSlot(SLOTTYPE::RIGHT_HAND_EXCLUSIVE))
3859 return false;
3861 // if the current item we wants to drop is a dagger, check if right hand is a sword or a dagger
3862 if (pIS->ItemType == ITEM_TYPE::DAGGER)
3864 if (pRightHandIS->ItemType != ITEM_TYPE::DAGGER && pRightHandIS->ItemType != ITEM_TYPE::SWORD)
3865 return false;
3868 else
3870 // If nothing valid in right hand cant drop a dagger
3871 if (pIS->ItemType == ITEM_TYPE::DAGGER)
3872 return false;
3876 // Check if the ammo has the same type as the hand containing the weapon
3877 if (_OtherHandItemFilter && _ItemSlot == SLOTTYPE::AMMO)
3879 CSheetId sheetId(_OtherHandItemFilter->getSheetId());
3880 CEntitySheet *pESWeapon = SheetMngr.get(sheetId);
3881 if (pESWeapon == NULL || pESWeapon->type() != CEntitySheet::ITEM)
3882 return false;
3883 CItemSheet *pISWeapon = (CItemSheet *)pESWeapon;
3884 if (pISWeapon->Family != ITEMFAMILY::RANGE_WEAPON)
3885 return false;
3886 if (pIS->Family != ITEMFAMILY::AMMO)
3887 return false;
3888 if (pISWeapon->RangeWeapon.Skill != pIS->Ammo.Skill)
3889 return false;
3892 // ok, can drop!
3893 return true;
3896 // default: cannot drop
3897 return false;
3900 // ***************************************************************************
3901 void CDBCtrlSheet::updateActualType() const
3903 if (_Type == SheetType_Auto)
3905 TSheetType newType;
3906 if (isMission())
3908 newType = SheetType_Mission;
3910 else if (isSkill())
3912 newType = SheetType_Skill;
3914 else
3916 // get type from sheet id
3917 CEntitySheet *es = SheetMngr.get(CSheetId(_SheetId.getSInt32()));
3918 if (!es)
3920 newType = SheetType_Item;
3922 else
3924 switch(es->type())
3926 case CEntitySheet::ITEM: newType = SheetType_Item; break;
3927 case CEntitySheet::PACT: newType = SheetType_Pact; break;
3928 case CEntitySheet::SBRICK: newType = SheetType_SBrick; break;
3929 case CEntitySheet::SPHRASE: newType = SheetType_SPhrase; break;
3930 case CEntitySheet::OUTPOST_BUILDING: newType = SheetType_OutpostBuilding; break;
3931 default:
3932 newType = SheetType_Item;
3933 break;
3938 // if type changed, must reset some ctrl state (important for list sheet trade for instance else
3939 // new SPhrase can get aspect of old SItem (eg: Upper-Left MP Text and Redified color...)
3940 if(newType!=_ActualType)
3942 _ActualType= newType;
3943 const_cast<CDBCtrlSheet*>(this)->_Grayed= false;
3944 const_cast<CDBCtrlSheet*>(this)->_Useable= true;
3945 const_cast<CDBCtrlSheet*>(this)->_OptString.clear();
3946 const_cast<CDBCtrlSheet*>(this)->resetCharBitmaps();
3949 else
3951 _ActualType = _Type;
3955 // ***************************************************************************
3956 void CDBCtrlSheet::setType(CCtrlSheetInfo::TSheetType type)
3958 _ActualType = _Type = type;
3959 _NeedSetup = true;
3962 // ***************************************************************************
3963 void CDBCtrlSheet::resetAllTexIDs()
3965 _DispSheetBmpId = -1;
3966 _DispBackBmpId = -1;
3967 _DispOverBmpId = -1;
3968 _DispOver2BmpId = -1;
3969 _DispQuality = -1;
3970 _DispQuantity= -1;
3971 _Stackable= 1;
3972 _IconW = 0;
3973 _IconH = 0;
3975 _ItemInfoChanged = true;
3976 _EnchantIcons.clear();
3977 _BuffIcons.clear();
3978 _BoostIcons.clear();
3982 // ***************************************************************************
3983 CCtrlSheetInfo::TSheetType CDBCtrlSheet::getType() const
3985 if (_Type == SheetType_GuildFlag) return SheetType_GuildFlag;
3987 if (_Type != SheetType_Macro)
3989 if (_LastSheetId != _SheetId.getSInt32())
3991 updateActualType();
3992 _LastSheetId = _SheetId.getSInt32();
3993 _NeedSetup = true;
3995 return _ActualType;
3997 else
3999 return SheetType_Macro;
4003 // ***************************************************************************
4004 void CDBCtrlSheet::setBehaviour(TRADE_SLOT_TYPE::TTradeSlotType type)
4006 if (_HasTradeSlotType)
4008 _TradeSlotType.setSInt32(type);
4012 // ***************************************************************************
4013 void CDBCtrlSheet::copyAspect(CDBCtrlSheet *dest)
4015 dest->setType(getType());
4016 dest->setSheetId(getSheetId());
4017 if (!isSBrickOrSPhraseId() && !isMission())
4019 if (getUseQuality())
4021 dest->setUseQuality(true);
4022 if (_Quality.getNodePtr() != NULL)
4023 dest->setQuality(getQuality());
4024 dest->setReadQuantityFromSheetFlag(getReadQuantityFromSheetFlag());
4026 else
4028 dest->setUseQuality(false);
4030 if (getUseQuantity())
4032 dest->setUseQuantity(true);
4033 if (_Quantity.getNodePtr() != NULL)
4034 dest->setQuantity(getQuantity());
4036 else
4038 dest->setUseQuantity(false);
4040 // copy color for items
4041 sint col = getItemColor();
4042 if (col != -1) dest->setItemColor(col);
4043 // copy weight
4044 dest->setItemWeight(getItemWeight());
4045 // copy nameId
4046 dest->setItemNameId(getItemNameId());
4047 // copy info version
4048 dest->setItemInfoVersion(getItemInfoVersion());
4049 // copy enchant info
4050 dest->setEnchant(getEnchant());
4051 // copy faber faber quality
4052 dest->setItemRMClassType(getItemRMClassType());
4053 // copy faber faber stat type
4054 dest->setItemRMFaberStatType(getItemRMFaberStatType());
4055 // copy faber faber stat type
4056 dest->setItemRMFaberStatType(getItemRMFaberStatType());
4057 // copy prerequisit valid flag
4058 dest->setItemPrerequisitValid(getItemPrerequisitValid());
4059 // copy item serial
4060 dest->setItemSerial(getItemSerial());
4061 // copy item create time
4062 dest->setItemCreateTime(getItemCreateTime());
4064 // if brick, sphrase or sphraseId
4065 if(isSBrick() || isSPhrase() || isSPhraseId())
4067 // must reset dest Useable/Redifyed and slotType (in case precedent type was Item!)
4068 dest->setGrayed(false);
4069 dest->_Useable= true;
4070 dest->_OptString.clear();
4071 dest->resetCharBitmaps();
4073 // misc
4074 if (dest->_HasTradeSlotType) dest->setBehaviour(getBehaviour());
4075 dest->invalidateCoords();
4076 dest->initSheetSize();
4079 dest->_NeedSetup = true;
4082 // ***************************************************************************
4083 bool CDBCtrlSheet::sameAspect(CDBCtrlSheet *dest) const
4085 if( dest->getType() != getType() )
4086 return false;
4087 if( dest->getSheetId() != getSheetId() )
4088 return false;
4089 if (!isSBrickOrSPhraseId() && !isSPhrase())
4092 if( dest->getUseQuality() != getUseQuality() )
4093 return false;
4094 if( getUseQuality() && _Quality.getNodePtr() != NULL )
4096 if( dest->getQuality() != getQuality() )
4097 return false;
4099 if( dest->getUseQuantity() != getUseQuantity() )
4100 return false;
4101 if( getUseQuantity() && _Quantity.getNodePtr() != NULL )
4103 if( dest->getQuantity() != getQuantity() )
4104 return false;
4106 if( dest->getEnchant() != getEnchant() )
4107 return false;
4108 if( dest->getRMClassType() != getRMClassType() )
4109 return false;
4110 if( dest->getRMFaberStatType() != getRMFaberStatType() )
4111 return false;
4113 return false; // nico v : Items can be different because of their item info. So can't conclude about equality.
4114 // default to false for safety
4116 if (dest->_HasTradeSlotType)
4118 if( dest->getBehaviour() != getBehaviour() )
4119 return false;
4122 return true;
4125 // ***************************************************************************
4126 CDBCtrlSheet::TSheetCategory CDBCtrlSheet::getSheetCategory() const
4128 if (isSkill()) return Skill;
4129 if (getType() == SheetType_Pact) return Pact;
4130 if (getType() == SheetType_GuildFlag) return GuildFlag;
4131 if (getType() == SheetType_Mission) return Mission;
4132 if (isSPhrase()) return Phrase;
4133 return Item;
4136 // ***************************************************************************
4137 bool CDBCtrlSheet::isMission() const
4139 CCDBNodeBranch *root = getRootBranch();
4140 if (!root) return false;
4141 CCDBNodeLeaf *node = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("ICON"), false));
4142 return node != NULL;
4145 // ***************************************************************************
4146 void CDBCtrlSheet::setupInit()
4148 _SetupInit= true;
4150 // Init _OtherHandItemFilter (with the opti string)
4151 if( !_OptString.empty() )
4153 // typically replace "handl" with "handr" or vice versa
4154 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4155 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId (_Id, _OptString);
4156 CDBCtrlSheet *pOtherHand = dynamic_cast<CDBCtrlSheet*>(pElt);
4157 if( !pOtherHand || pOtherHand ->getType() != CCtrlSheetInfo::SheetType_Item )
4159 nlwarning("%s: other_hand_slot error", _Id.c_str());
4161 _OtherHandItemFilter= pOtherHand;
4165 // ***************************************************************************
4166 IListSheetBase *CDBCtrlSheet::getListSheetParent() const
4168 IListSheetBase *parent = dynamic_cast<IListSheetBase *>(_Parent);
4169 // ListSheetTrade double parent sons (intermeidate _List)
4170 if(!parent && _Parent)
4172 parent = dynamic_cast<IListSheetBase *>(_Parent->getParent());
4174 return parent;
4177 // ***************************************************************************
4178 sint CDBCtrlSheet::getIndexInParent() const
4180 IListSheetBase *parent= getListSheetParent();
4181 if (!parent) return -1;
4182 return parent->getIndexOf(this);
4185 // ***************************************************************************
4186 void CDBCtrlSheet::readFromMacro(const CMacroCmd &mc)
4188 if (_Type != SheetType_Macro) return;
4189 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4191 _DispBackBmpId = (mc.BitmapBack == 0xFF) ? -1 : pMCM->getTexIdBack(mc.BitmapBack);
4193 _DispOverBmpId = (mc.BitmapIcon == 0xFF) ? -1 : pMCM->getTexIdIcon(mc.BitmapIcon);
4195 _DispOver2BmpId = (mc.BitmapOver == 0xFF) ? -1 : pMCM->getTexIdOver(mc.BitmapOver);
4197 _OptString = mc.DispText;
4198 _NeedSetup = true;
4199 _MacroID = mc.ID;
4202 // ***************************************************************************
4203 void CDBCtrlSheet::writeToMacro(CMacroCmd &mc)
4205 uint i = 0;
4206 if (_Type != SheetType_Macro) return;
4207 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4209 // Find back
4210 if (_DispBackBmpId == -1)
4212 mc.BitmapBack = 0xFF;
4214 else
4216 i = 0;
4217 while (i != 255)
4219 if (pMCM->getTexIdBack(i) == _DispBackBmpId) break;
4220 i++;
4222 if (i == 255) nlwarning("cannot find back id for macro");
4223 mc.BitmapBack = i;
4226 // Find Icon
4227 if (_DispOverBmpId == -1)
4229 mc.BitmapIcon = 0xFF;
4231 else
4233 i = 0;
4234 while (i != 255)
4236 if (pMCM->getTexIdIcon(i) == _DispOverBmpId) break;
4237 i++;
4239 if (i == 255) nlwarning("cannot find icon id for macro");
4240 mc.BitmapIcon = i;
4243 // Find over
4244 if (_DispOver2BmpId == -1)
4246 mc.BitmapOver = 0xFF;
4248 else
4250 i = 0;
4251 while (i != 255)
4253 if (pMCM->getTexIdOver(i) == _DispOver2BmpId) break;
4254 i++;
4256 if (i == 255) nlwarning("cannot find over id for macro");
4257 mc.BitmapOver = i;
4260 mc.DispText = _OptString;
4261 mc.ID = _MacroID;
4265 // ***************************************************************************
4266 void CDBCtrlSheet::setMacroBack(uint8 nb)
4268 if (_Type != SheetType_Macro) return;
4269 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4270 _DispBackBmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdBack(nb);
4273 // ***************************************************************************
4274 void CDBCtrlSheet::setMacroIcon(uint8 nb)
4276 if (_Type != SheetType_Macro) return;
4277 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4278 _DispOverBmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdIcon(nb);
4281 // ***************************************************************************
4282 void CDBCtrlSheet::setMacroOver(uint8 nb)
4284 if (_Type != SheetType_Macro) return;
4285 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4286 _DispOver2BmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdOver(nb);
4289 // ***************************************************************************
4290 void CDBCtrlSheet::setMacroText(const std::string &mcText)
4292 _OptString = mcText;
4293 _NeedSetup = true;
4296 // ***************************************************************************
4297 bool CDBCtrlSheet::isSheetValid() const
4299 // get the actual type
4300 TSheetType type= getType();
4302 sint32 sid = 0;
4303 bool validSheet = false;
4305 if ((type != SheetType_Macro) && (type != SheetType_Skill))
4307 sid = getSheetId();
4308 validSheet = (sid!=0);
4310 // different test according to type
4311 switch(type)
4313 // brick OK?
4314 // always for macros and skills enums
4315 case SheetType_Macro:
4316 case SheetType_Skill:
4317 validSheet= true;
4318 break;
4319 case SheetType_GuildFlag:
4320 // sid == name, quality == icon if both are != 0 then its a valid guild flag
4321 validSheet= (sid!=0)&&(_Quality.getSInt32() != 0);
4322 break;
4323 // SBrick OK?
4324 case SheetType_SBrick:
4325 validSheet= validSheet && CSBrickManager::getInstance()->getBrick(CSheetId((uint32)sid));
4326 break;
4327 case SheetType_SPhraseId:
4328 // Suppose phrase always valid but if 0.
4329 break;
4330 // Same for Items, Pact, and SPhrase
4331 default:
4332 validSheet= validSheet && SheetMngr.get(CSheetId((uint32)sid));
4333 validSheet= validSheet && (!_ItemWeared);
4334 break;
4337 // TODO_BRICK: SPhrase / SPhraseId????
4339 return validSheet;
4342 // ***************************************************************************
4343 bool CDBCtrlSheet::isSheetEqual(CDBCtrlSheet *pCS) const
4345 if (!pCS)
4346 return false;
4348 return getInventoryIndex() == pCS->getInventoryIndex() && getIndexInDB() == pCS->getIndexInDB();
4351 // ***************************************************************************
4352 // GUILD_FLAG
4353 // ***************************************************************************
4355 // ***************************************************************************
4356 CRGBA CDBCtrlSheet::getGuildColor1() const
4358 CRGBA col = CRGBA::White;
4359 if (_Type != SheetType_GuildFlag) return col;
4360 uint64 nGuildIcon = _Quality.getSInt64();
4361 return CGuildManager::iconGetColor1(nGuildIcon);
4364 // ***************************************************************************
4365 CRGBA CDBCtrlSheet::getGuildColor2() const
4367 CRGBA col=CRGBA::White;
4368 if (_Type != SheetType_GuildFlag) return col;
4369 uint64 nGuildIcon = _Quality.getSInt64();
4370 return CGuildManager::iconGetColor2(nGuildIcon);
4373 // ***************************************************************************
4374 sint32 CDBCtrlSheet::getGuildBack() const
4376 sint32 back = 0;
4377 if (_Type != SheetType_GuildFlag) return back;
4378 uint64 nGuildIcon = _Quality.getSInt64();
4379 return CGuildManager::iconGetBack(nGuildIcon);
4382 // ***************************************************************************
4383 sint32 CDBCtrlSheet::getGuildSymbol() const
4385 sint32 symb = 0;
4386 if (_Type != SheetType_GuildFlag) return symb;
4387 uint64 nGuildIcon = _Quality.getSInt64();
4388 return CGuildManager::iconGetSymbol(nGuildIcon);
4391 // ***************************************************************************
4392 bool CDBCtrlSheet::getInvertGuildSymbol() const
4394 if (_Type != SheetType_GuildFlag) return false;
4395 uint64 nGuildIcon = _Quality.getSInt64();
4396 return CGuildManager::iconGetInvertSymbol(nGuildIcon);
4399 // ***************************************************************************
4400 void CDBCtrlSheet::setGuildColor1(CRGBA col)
4402 if (_Type != SheetType_GuildFlag) return;
4403 // Clean up bits
4404 uint64 nGuildIcon = _Quality.getSInt64();
4405 CGuildManager::iconSetColor1(nGuildIcon, col);
4406 _Quality.setSInt64(nGuildIcon);
4409 // ***************************************************************************
4410 void CDBCtrlSheet::setGuildColor2(CRGBA col)
4412 if (_Type != SheetType_GuildFlag) return;
4413 // Clean up bits
4414 uint64 nGuildIcon = _Quality.getSInt64();
4415 CGuildManager::iconSetColor2(nGuildIcon, col);
4416 _Quality.setSInt64(nGuildIcon);
4419 // ***************************************************************************
4420 void CDBCtrlSheet::setGuildBack(sint32 n)
4422 if (_Type != SheetType_GuildFlag) return;
4423 // Clean up bits
4424 uint64 nGuildIcon = _Quality.getSInt64();
4425 CGuildManager::iconSetBack(nGuildIcon, (uint8)n);
4426 _Quality.setSInt64(nGuildIcon);
4429 // ***************************************************************************
4430 void CDBCtrlSheet::setGuildSymbol(sint32 n)
4432 if (_Type != SheetType_GuildFlag) return;
4433 // Clean up bits
4434 uint64 nGuildIcon = _Quality.getSInt64();
4435 CGuildManager::iconSetSymbol(nGuildIcon, (uint8)n);
4436 _Quality.setSInt64(nGuildIcon);
4439 // ***************************************************************************
4440 void CDBCtrlSheet::setInvertGuildSymbol(bool b)
4442 if (_Type != SheetType_GuildFlag) return;
4443 // Clean up bits
4444 uint64 nGuildIcon = _Quality.getSInt64();
4445 CGuildManager::iconSetInvertSymbol(nGuildIcon, b);
4446 _Quality.setSInt64(nGuildIcon);
4449 // ***************************************************************************
4450 void CDBCtrlSheet::setSlot(const std::string &textureName)
4452 CInterfaceManager *pIM = CInterfaceManager::getInstance();
4453 CViewRenderer &rVR = *CViewRenderer::getInstance();
4454 _DispSlotBmpId = rVR.getTextureIdFromName (textureName);
4455 rVR.getTextureSizeFromId (_DispSlotBmpId, _W, _H);
4456 _DrawSlot = true;
4459 // ***************************************************************************
4460 // SBrick
4461 // ***************************************************************************
4463 // ***************************************************************************
4464 bool CDBCtrlSheet::isSPhraseIdMemory() const
4466 if(!isSPhraseId())
4467 return false;
4469 // test if mem match
4470 if( 0 == _DbBranchName.compare(0, PHRASE_DB_MEMORY.size(), PHRASE_DB_MEMORY) )
4471 return true;
4472 return false;
4475 // ***************************************************************************
4476 bool CDBCtrlSheet::isMacroMemory() const
4478 if(!isMacro())
4479 return false;
4481 // test if mem match
4482 if( 0 == _DbBranchName.compare(0, PHRASE_DB_MEMORY.size(), PHRASE_DB_MEMORY) )
4483 return true;
4484 return false;
4487 // ***************************************************************************
4488 uint8 CDBCtrlSheet::getItemInfoVersion() const
4490 CCDBNodeLeaf *node = getItemInfoVersionPtr();
4491 return node ? (uint8) node->getValue8() : 0;
4494 // ***************************************************************************
4495 CCDBNodeLeaf *CDBCtrlSheet::getItemInfoVersionPtr() const
4497 CCDBNodeBranch *root = getRootBranch();
4498 if (!root) return NULL;
4499 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("INFO_VERSION"), false));
4502 // ***************************************************************************
4503 void CDBCtrlSheet::setItemInfoVersion(uint8 infoVersion)
4505 CCDBNodeLeaf *node = getItemInfoVersionPtr();
4506 if (node) node->setValue8((sint8) infoVersion);
4509 // ***************************************************************************
4510 CCDBNodeLeaf *CDBCtrlSheet::getItemWeightPtr() const
4512 CCDBNodeBranch *root = getRootBranch();
4513 if (!root) return NULL;
4514 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("WEIGHT"), false));
4517 // ***************************************************************************
4518 uint16 CDBCtrlSheet::getItemWeight() const
4520 CCDBNodeLeaf *node = getItemWeightPtr();
4521 return node ? (uint16) node->getValue16() : 0;
4524 // ***************************************************************************
4525 void CDBCtrlSheet::setItemWeight(uint16 weight)
4527 CCDBNodeLeaf *node = getItemWeightPtr();
4528 if (node) node->setValue16((sint16) weight);
4531 // ***************************************************************************
4532 CCDBNodeLeaf *CDBCtrlSheet::getItemLockedPtr() const
4534 CCDBNodeBranch *root = getRootBranch();
4535 if (!root) return NULL;
4536 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("LOCKED"), false));
4539 // ***************************************************************************
4540 uint16 CDBCtrlSheet::getItemLocked() const
4542 CCDBNodeLeaf *node = getItemLockedPtr();
4543 if (!node) return -1;
4544 return (sint) node->getValue32();
4547 // ***************************************************************************
4548 void CDBCtrlSheet::setItemLocked(uint16 lock)
4550 CCDBNodeLeaf *node = getItemLockedPtr();
4551 if (!node) return;
4552 node->setValue32(lock);
4555 // ***************************************************************************
4556 sint32 CDBCtrlSheet::getItemPrice() const
4558 CCDBNodeLeaf *node = getItemPricePtr();
4559 if (!node) return 0;
4560 return node->getValue32();
4563 // ***************************************************************************
4564 CCDBNodeLeaf *CDBCtrlSheet::getItemPricePtr() const
4566 CCDBNodeBranch *root = getRootBranch();
4567 if (!root) return NULL;
4568 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("PRICE"), false));
4571 // ***************************************************************************
4572 void CDBCtrlSheet::setItemPrice(sint32 price)
4574 CCDBNodeLeaf *node = getItemPricePtr();
4575 if (!node) return;
4576 node->setValue32(price);
4579 // ***************************************************************************
4580 sint32 CDBCtrlSheet::getItemResaleFlag() const
4582 CCDBNodeLeaf *node = getItemResaleFlagPtr();
4583 if (!node) return 0;
4584 return node->getValue32();
4587 // ***************************************************************************
4588 CCDBNodeLeaf *CDBCtrlSheet::getItemResaleFlagPtr() const
4590 CCDBNodeBranch *root = getRootBranch();
4591 if (!root) return NULL;
4592 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("RESALE_FLAG"), false));
4595 // ***************************************************************************
4596 void CDBCtrlSheet::setItemResaleFlag(sint32 rf)
4598 CCDBNodeLeaf *node = getItemResaleFlagPtr();
4599 if (!node) return;
4600 node->setValue32(rf);
4603 // ***************************************************************************
4604 sint32 CDBCtrlSheet::getItemCreateTime() const
4606 CCDBNodeLeaf *node = getItemCreateTimePtr();
4607 if (!node) return 0;
4608 return node->getValue32();
4611 // ***************************************************************************
4612 CCDBNodeLeaf *CDBCtrlSheet::getItemCreateTimePtr() const
4614 CCDBNodeBranch *root = getRootBranch();
4615 if (!root) return NULL;
4616 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("CREATE_TIME"), false));
4619 // ***************************************************************************
4620 void CDBCtrlSheet::setItemCreateTime(sint32 ct)
4622 CCDBNodeLeaf *node = getItemCreateTimePtr();
4623 if (!node) return;
4624 node->setValue32(ct);
4627 // ***************************************************************************
4628 sint32 CDBCtrlSheet::getItemSerial() const
4630 CCDBNodeLeaf *node = getItemSerialPtr();
4631 if (!node) return 0;
4632 return node->getValue32();
4635 // ***************************************************************************
4636 CCDBNodeLeaf *CDBCtrlSheet::getItemSerialPtr() const
4638 CCDBNodeBranch *root = getRootBranch();
4639 if (!root) return NULL;
4640 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("SERIAL"), false));
4643 // ***************************************************************************
4644 void CDBCtrlSheet::setItemSerial(sint32 rf)
4646 CCDBNodeLeaf *node = getItemSerialPtr();
4647 if (!node) return;
4648 node->setValue32(rf);
4651 // ***************************************************************************
4652 bool CDBCtrlSheet::getLockedByOwner() const
4654 return (getItemResaleFlag() == BOTCHATTYPE::ResaleKOLockedByOwner);
4657 // ***************************************************************************
4658 bool CDBCtrlSheet::canOwnerLock() const
4660 return (NULL != getItemResaleFlagPtr());
4663 // ***************************************************************************
4664 sint32 CDBCtrlSheet::getItemSellerType() const
4666 CCDBNodeLeaf *node = getItemSellerTypePtr();
4667 if (!node) return 0;
4668 return node->getValue32();
4671 // ***************************************************************************
4672 CCDBNodeLeaf *CDBCtrlSheet::getItemSellerTypePtr() const
4674 CCDBNodeBranch *root = getRootBranch();
4675 if (!root) return NULL;
4676 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("SELLER_TYPE"), false));
4679 // ***************************************************************************
4680 void CDBCtrlSheet::setItemSellerType(sint32 rf)
4682 CCDBNodeLeaf *node = getItemSellerTypePtr();
4683 if (!node) return;
4684 node->setValue32(rf);
4687 // ***************************************************************************
4688 RM_CLASS_TYPE::TRMClassType CDBCtrlSheet::getItemRMClassType() const
4690 CCDBNodeLeaf *node = getItemRMClassTypePtr();
4691 return (RM_CLASS_TYPE::TRMClassType) (node ? node->getValue32() : 0);
4694 // ***************************************************************************
4695 void CDBCtrlSheet::setItemRMClassType(sint32 fq)
4697 CCDBNodeLeaf *node = getItemRMClassTypePtr();
4698 if (!node) return;
4699 node->setValue32(fq);
4702 // ***************************************************************************
4703 RM_FABER_STAT_TYPE::TRMStatType CDBCtrlSheet::getItemRMFaberStatType() const
4705 CCDBNodeLeaf *node = getItemRMFaberStatTypePtr();
4706 return (RM_FABER_STAT_TYPE::TRMStatType) (node ? node->getValue32() : 0);
4709 // ***************************************************************************
4710 void CDBCtrlSheet::setItemRMFaberStatType(sint32 fss)
4712 CCDBNodeLeaf *node = getItemRMFaberStatTypePtr();
4713 if (!node) return;
4714 node->setValue32(fss);
4717 // ***************************************************************************
4718 bool CDBCtrlSheet::getItemPrerequisitValid() const
4720 CCDBNodeLeaf *node = getItemPrerequisitValidPtr();
4721 return (bool) (node ? node->getValueBool() : true);
4724 // ***************************************************************************
4725 CCDBNodeLeaf *CDBCtrlSheet::getItemPrerequisitValidPtr() const
4727 CCDBNodeBranch *root = getRootBranch();
4728 if (!root) return NULL;
4729 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("PREREQUISIT_VALID"), false));
4732 // ***************************************************************************
4733 void CDBCtrlSheet::setItemPrerequisitValid(bool prv)
4735 CCDBNodeLeaf *node = getItemPrerequisitValidPtr();
4736 if (!node) return;
4737 node->setValueBool(prv);
4740 // ***************************************************************************
4741 void CDBCtrlSheet::initArmourColors()
4743 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4745 for(uint col = 0; col < RM_COLOR::NumColors; ++col)
4747 _ArmourColor[col] = CRGBA::White;
4748 std::string defineName= "armour_color_" + toString(col);
4749 std::string colVal= CWidgetManager::getInstance()->getParser()->getDefine(defineName);
4750 if(!colVal.empty())
4751 _ArmourColor[col] = convertColor(colVal.c_str());
4756 // ***************************************************************************
4757 string CDBCtrlSheet::getItemActualName() const
4759 const CItemSheet *pIS= asItemSheet();
4760 if(!pIS)
4761 return string();
4762 else
4764 string ret;
4765 // If NameId not 0, get from StringManager
4766 uint32 nameId= getItemNameId();
4767 if(nameId)
4769 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
4770 pSMC->getDynString(nameId, ret);
4772 // else get standard localized version
4773 else
4775 ret = STRING_MANAGER::CStringManagerClient::getItemLocalizedName(pIS->Id);
4778 if (pIS->Family == ITEMFAMILY::SCROLL_R2)
4780 const R2::TMissionItem *mi = R2::getEditor().getPlotItemInfos(getSheetId());
4781 if (mi) return mi->Name.toUtf8();
4783 // if item is not a mp, append faber_quality & faber_stat_type
4784 // Don't append quality and stat type for Named Items!!!
4785 if (!nameId &&
4786 (pIS->Family == ITEMFAMILY::ARMOR ||
4787 pIS->Family == ITEMFAMILY::MELEE_WEAPON ||
4788 pIS->Family == ITEMFAMILY::RANGE_WEAPON ||
4789 pIS->Family == ITEMFAMILY::AMMO ||
4790 pIS->Family == ITEMFAMILY::SHIELD ||
4791 pIS->Family == ITEMFAMILY::JEWELRY)
4794 // get description string for item format
4795 std::string formatID = getItemRMFaberStatType() != RM_FABER_STAT_TYPE::Unknown ? "uihelpItemFaberPrefixAndSuffix" : "uihelpItemFaberPrefix";
4796 string format;
4797 if (!CI18N::hasTranslation(formatID))
4799 format = "%p %n %s"; // not found, uses default string
4801 else
4803 format = CI18N::get(formatID);
4805 // suffix
4806 strFindReplace(format, "%p", RM_CLASS_TYPE::toLocalString(getItemRMClassType()));
4807 // name
4808 strFindReplace(format, "%n", ret);
4809 // prefix
4810 strFindReplace(format, "%s", CI18N::get(toString("mpstatItemQualifier%d", (int) getItemRMFaberStatType()).c_str()));
4813 ret = format;
4815 return ret;
4819 // ***************************************************************************
4820 void CDBCtrlSheet::updateArmourColor(sint8 col)
4822 // bkup index cache (bkup -1 too)
4823 _ArmourColorIndex= col;
4825 if(_ArmourColorIndex>=0 && _ArmourColorIndex<=7)
4827 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4828 CViewRenderer &rVR= *CViewRenderer::getInstance();
4830 // if the BMP have not been correctly setuped
4831 if(!_ArmourColorBmpOk)
4833 _ArmourColorBmpOk= true;
4835 if (_DispOverBmpId != -1)
4837 _DispOver2BmpId = _DispOverBmpId;
4839 std::string iconName = rVR.getTextureNameFromId(_DispSheetBmpId);
4840 std::string maskName = CFile::getFilenameWithoutExtension(iconName) + "_mask." + CFile::getExtension(iconName);
4841 _DispOverBmpId = rVR.getTextureIdFromName (maskName);
4844 // new true color
4845 _PackedArmourColor = _ArmourColor[col].getPacked();
4849 // ***************************************************************************
4850 bool CDBCtrlSheet::checkItemRequirement()
4852 if(getType()!=SheetType_Item)
4853 return true;
4855 // If quality not used, well, cannot check item requirement.
4856 if(!_UseQuality)
4857 return true;
4859 // NB: we cannot test directly _Useable, because callers typically call this method BEFORE updateCoords()
4861 // If this is not the same sheet/quality, need to resetup charac requirement
4863 sint32 sheet = _SheetId.getSInt32();
4864 if (_LastSheetId != sheet || _NeedSetup || _Quality.getSInt32()!=_DispQuality)
4866 // NB: don't update cache, leave this feature to updateCoords()
4867 // Special Item requirement
4868 updateItemCharacRequirement(sheet);
4871 // at each frame, must test for Redifyed (player carac does not met item requirement)
4872 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4874 bool retVal = pIM->isItemCaracRequirementMet(_ItemCaracReqType, _ItemCaracReqValue);
4876 if (retVal && _ItemSheet)
4878 if (_ItemSheet->RequiredCharac != CHARACTERISTICS::Unknown && _ItemSheet->RequiredCharacLevel>0)
4879 retVal = pIM->isItemCaracRequirementMet(_ItemSheet->RequiredCharac, _ItemSheet->RequiredCharacLevel);
4881 if (retVal && _ItemSheet->RequiredSkillLevel > 0 && _ItemSheet->RequiredSkill != SKILLS::unknown)
4882 _Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
4884 return retVal;
4886 return _Useable = _PrerequisitValid.getBool();
4890 bool NoOpForCCtrlSheetInfo_Serial = false; // Prevent an assert in CDBCtrlSheet::serial (set externally) for a very specific case.
4891 // The only case where an empty implementation is ok is for r2 in edition mode
4892 // when building in scene interface for entities (the CDBCtrlSheet are hidden then ...!) /
4894 // ***************************************************************************
4895 void CDBCtrlSheet::serial(NLMISC::IStream &f)
4897 CCtrlBase::serial(f);
4898 if (NoOpForCCtrlSheetInfo_Serial) return; // no-op for now
4899 nlassert(0); // !! IMPLEMENT ME !!
4902 // ***************************************************************************
4903 std::string CDBCtrlSheet::getContextHelpWindowName() const
4905 if (getType() == CCtrlSheetInfo::SheetType_SPhraseId)
4907 return "action_context_help";
4909 if (getType() == CCtrlSheetInfo::SheetType_Item)
4911 const CItemSheet *item= asItemSheet();
4912 if(item && useItemInfoForFamily(item->Family))
4914 if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL)
4916 return "crystallized_spell_context_help";
4918 else
4920 return "buff_item_context_help";
4924 return CCtrlBase::getContextHelpWindowName();
4927 // ***************************************************************************
4928 void CDBCtrlSheet::setRegenTextFct(const std::string &s)
4930 _RegenTextFct = s;
4931 _RegenTextFctLua = startsWith(s, "lua:");
4934 // ***************************************************************************
4935 void CDBCtrlSheet::setRegenTickRange(const CTickRange &tickRange)
4937 _RegenTickRange = tickRange;
4940 // ***************************************************************************
4941 void CDBCtrlSheet::startNotifyAnim()
4943 _NotifyAnimEndTime = T1 + NOTIFY_ANIM_MS_DURATION;