Fix css style order when using external css files
[ryzomcore.git] / ryzom / client / src / interface_v3 / dbctrl_sheet.cpp
blobf24137f233fde9439478ef7765ff6e573bbdeeb1
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 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"
60 extern CSheetManager SheetMngr;
62 using namespace std;
63 using namespace NLMISC;
64 using namespace NL3D;
65 using namespace STRING_MANAGER;
67 NLMISC::CSmartPtr<CSPhraseComAdpater> CDBCtrlSheet::_PhraseAdapter;
69 CDBCtrlSheet *CDBCtrlSheet::_CurrSelection = NULL;
70 CDBCtrlSheet *CDBCtrlSheet::_CurrMenuSheet = NULL;
71 UMaterial CDBCtrlSheet::_GuildMat;
74 NLMISC::CRGBA CDBCtrlSheet::_ArmourColor[RM_COLOR::NumColors];
76 REGISTER_UI_CLASS(CDBCtrlSheet)
79 const uint64 NOTIFY_ANIM_MS_DURATION = 1000;
81 // state kept and changed by UI:SAVE:SHOW_ICON_BUFFS
82 bool CDBCtrlSheet::_ShowIconBuffs = true;
84 // ***************************************************************************
86 void CControlSheetInfoWaiter::sendRequest()
88 Requesting = true;
89 getInventory().addItemInfoWaiter(this);
92 void CControlSheetInfoWaiter::infoReceived()
94 if (!Requesting) {
95 return;
98 getInventory().removeItemInfoWaiter(this);
99 infoValidated();
100 CtrlSheet->infoReceived();
101 Requesting = false;
105 string CControlSheetInfoWaiter::infoValidated() const
107 #ifdef RYZOM_LUA_UCSTRING
108 ucstring help; // Compatibility
109 #else
110 string help;
111 #endif
112 if (CtrlSheet && !LuaMethodName.empty())
114 // delegate setup of context he help ( & window ) to lua
115 CInterfaceManager *im = CInterfaceManager::getInstance();
116 CLuaState *ls= CLuaManager::getInstance().getLuaState();
118 CLuaStackRestorer lsr(ls, 0);
120 CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)CtrlSheet);
121 ls->pushGlobalTable();
122 CLuaObject game(*ls);
123 game = game["game"];
124 game.callMethodByNameNoThrow(LuaMethodName.c_str(), 1, 1);
126 // retrieve result from stack
127 if (!ls->empty())
129 #ifdef RYZOM_LUA_UCSTRING
130 CLuaIHM::pop(*ls, help);
131 #else
132 help = ls->toString(-1);
133 ls->pop();
134 #endif
136 else
138 nlwarning(toString("Ucstring result expected when calling '%s', possible script error", LuaMethodName.c_str()).c_str());
143 #ifdef RYZOM_LUA_UCSTRING
144 return help.toUtf8();
145 #else
146 return help;
147 #endif
150 // ***************************************************************************
151 int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls)
153 CLuaIHM::pushUIOnStack(ls, dynamic_cast<CInterfaceElement *>( dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) ));
154 return 1;
157 // ***************************************************************************
158 int CDBCtrlSheet::luaGetItemInfo(CLuaState &ls)
160 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet *>(this);
161 uint32 itemSlotId = getInventory().getItemSlotId(ctrlSheet);
162 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
164 ls.newTable();
165 CLuaObject out(ls);
166 // for now all but magic
167 out.setValue("CurrentDamage", itemInfo.CurrentDamage);
168 out.setValue("MaxDamage", itemInfo.MaxDamage);
169 out.setValue("DodgeModifier", itemInfo.DodgeModifier);
170 out.setValue("ParryModifier", itemInfo.ParryModifier);
171 out.setValue("AdversaryDodgeModifier", itemInfo.AdversaryDodgeModifier);
172 out.setValue("AdversaryParryModifier", itemInfo.AdversaryParryModifier);
173 out.setValue("Hp", itemInfo.Hp);
174 out.setValue("HpMax", itemInfo.HpMax);
175 out.setValue("Range", itemInfo.Range);
176 out.setValue("HpBuff", itemInfo.HpBuff);
177 out.setValue("SapBuff", itemInfo.SapBuff);
178 out.setValue("StaBuff", itemInfo.StaBuff);
179 out.setValue("FocusBuff", itemInfo.FocusBuff);
180 out.setValue("SapLoadCurrent", itemInfo.SapLoadCurrent);
181 out.setValue("SapLoadMax", itemInfo.SapLoadMax);
182 out.setValue("ProtectionFactor", itemInfo.ProtectionFactor);
183 out.setValue("MaxSlashingProtection", itemInfo.MaxSlashingProtection);
184 out.setValue("MaxPiercingProtection", itemInfo.MaxPiercingProtection);
185 out.setValue("MaxBluntProtection", itemInfo.MaxBluntProtection);
186 out.setValue("WearEquipmentMalus", itemInfo.WearEquipmentMalus);
187 out.push();
189 return 1;
192 // ***************************************************************************
193 int CDBCtrlSheet::luaGetName(CLuaState &ls)
195 #ifdef RYZOM_LUA_UCSTRING
196 CLuaIHM::push(ls, ucstring::makeFromUtf8(getItemActualName()));
197 #else
198 ls.push(getItemActualName());
199 #endif
200 return 1;
203 // **********************************************************************************************************
204 class LuaInfoWaiter : public IItemInfoWaiter
206 public:
207 volatile bool done;
209 public:
210 virtual void infoReceived();
214 void LuaInfoWaiter::infoReceived()
216 getInventory().removeItemInfoWaiter(this);
217 this->done = true;
220 static LuaInfoWaiter luaInfoWaiter;
222 // ***************************************************************************
223 int CDBCtrlSheet::luaGetCreatorName(CLuaState &ls)
225 uint32 itemSlotId = getInventory().getItemSlotId(this);
226 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
227 string creatorName;
228 STRING_MANAGER::CStringManagerClient::instance()->getString(itemInfo.CreatorName, creatorName);
229 #ifdef RYZOM_LUA_UCSTRING
230 CLuaIHM::push(ls, ucstring::makeFromUtf8(creatorName)); // FIXME: Lua UTF-8
231 #else
232 ls.push(creatorName);
233 #endif
235 return 1;
238 // ***************************************************************************
239 int CDBCtrlSheet::luaWaitInfo(CLuaState &ls)
241 static bool sent = false;
242 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
243 uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
244 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
246 if (sent || itemInfo.versionInfo != 0)
248 ls.push((bool)(luaInfoWaiter.done));
249 if (luaInfoWaiter.done)
250 sent = false;
251 return luaInfoWaiter.done ? 1 : 0;
253 else
255 luaInfoWaiter.ItemSlotId = itemSlotId;
256 luaInfoWaiter.ItemSheet = this->getSheetId();
257 luaInfoWaiter.done = false;
258 getInventory().addItemInfoWaiter(&luaInfoWaiter);
259 sent = true;
261 return 0;
264 // ***************************************************************************
265 int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
268 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
269 uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
270 CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
272 CInterfaceManager *pIM = CInterfaceManager::getInstance();
273 CSBrickManager *pBM= CSBrickManager::getInstance();
275 uint currentBrick = 0;
276 uint i;
277 for(i=0;i<itemInfo.Enchantment.Bricks.size();i++)
279 //if ( ! (pBM->getBrick(itemInfo.Enchantment.Bricks[i])->isCredit() || pBM->getBrick(itemInfo.Enchantment.Bricks[i])->isParameter()))
281 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:VARIABLES:CRYSTALBRICKS:%d:SHEET", currentBrick++));
282 if(node)
283 node->setValue32(itemInfo.Enchantment.Bricks[i].asInt());
288 // Reset other to 0.
289 for(;;currentBrick++)
291 CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:VARIABLES:CRYSTALBRICKS:%d:SHEET", currentBrick), false);
292 if(node)
293 node->setValue32(0);
294 else
295 break;
297 return 1;
301 // ***************************************************************************
303 // ----------------------------------------------------------------------------
304 CCtrlSheetInfo::CCtrlSheetInfo()
306 _Type = CCtrlSheetInfo::SheetType_Item;
307 _DispNoSheetBmpId = -1;
308 _InterfaceColor= true;
309 _SheetSelectionGroup = -1;
310 _UseQuality = true;
311 _DisplayItemQuality = 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 _DispSlotBmpId= -1;
514 _DispBackBmpId = -1;
515 _DispSheetBmpId = -1;
516 _DispOverBmpId = -1;
517 _DispOver2BmpId= -1;
518 _CanDrop = false;
519 _Stackable= 1;
520 _DispQuality= -1;
521 _DispQuantity= -1;
522 _Over = false;
523 _TextureIdOver= -1;
524 _IndexInDB= 0;
525 _SecondIndexInDB= 0;
526 _ShortCut= false;
527 _SheetColor= CRGBA::White;
528 _OtherHandItemFilter= NULL;
529 _ActualType = _Type;
530 _ItemWeared= false;
531 _ItemBeastGrayed= false;
532 _Grayed= false;
533 _Useable= true;
534 _GrayedLink= NULL;
535 _NeedSetup= true;
536 _ItemInfoChanged = true;
537 _IconW = 0;
538 _IconH = 0;
539 _SetupInit= false;
540 _IconBackColor= CRGBA::White;
541 _IconColor= CRGBA::White;
542 _IconOverColor= CRGBA::White;
543 _IconOver2Color= CRGBA::White;
544 _PackedArmourColor= 0;
545 _MacroID = -1;
546 _GuildBack = _GuildSymb = NULL;
547 _UseGuildIcon = false;
548 _GuildIcon = NLMISC::CSheetId::Unknown;
549 _DrawSlot= true;
550 _ItemCaracReqType= CHARACTERISTICS::Unknown;
551 _ItemCaracReqValue= 0;
552 _ArmourColorFromDB= false;
553 _ArmourColorBmpOk= false;
554 _ArmourColorIndex= 0;
555 _UserColor= NULL;
556 _ItemSheet = NULL;
557 _ItemRMClassType= NULL;
558 _ItemRMFaberStatType= NULL;
559 _NotifyAnimEndTime = 0;
561 _HpBuffIcon = "ico_heal.tga";
562 _SapBuffIcon = "ico_sap.tga";
563 _StaBuffIcon = "ico_stamina.tga";
564 _FocusBuffIcon = "ico_focus.tga";
566 _RegenText = NULL;
567 _RegenTextValue = 0;
570 // ----------------------------------------------------------------------------
571 CDBCtrlSheet::~CDBCtrlSheet()
573 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
575 if (_ItemInfoWaiter.Requesting)
577 getInventory().removeItemInfoWaiter(&_ItemInfoWaiter);
580 if (_GuildBack)
582 if (Driver)
583 Driver->deleteTextureFile(_GuildBack);
584 _GuildBack = NULL;
586 if (_GuildSymb)
588 if (Driver)
589 Driver->deleteTextureFile(_GuildSymb);
590 _GuildSymb = NULL;
592 if (_RegenText)
594 delete _RegenText;
595 _RegenText = NULL;
598 // ensure erase static
599 if(this==_CurrMenuSheet) _CurrMenuSheet = NULL;
600 if(this == dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) )
601 setDraggedSheet( NULL );
602 if(this==_CurrSelection) _CurrSelection = NULL;
605 // ----------------------------------------------------------------------------
606 bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
608 CXMLAutoPtr prop;
610 if (! CCtrlBase::parse(cur,parentGroup) )
612 string tmp = "cannot parse view:"+getId()+", parent:"+parentGroup->getId();
613 nlinfo(tmp.c_str());
614 return false;
617 // parse the common ctrl info
618 if(!parseCtrlInfo(cur, parentGroup))
619 return false;
621 prop = (char*) xmlGetProp( cur, (xmlChar*)"dragable" );
622 if (prop)
623 setDraggable( CInterfaceElement::convertBool(prop) );
624 else
625 setDraggable( false );
627 if (_Type != SheetType_Macro)
629 prop = (char*) xmlGetProp( cur, (xmlChar*)"value" );
630 if (prop)
631 initSheet (string((const char*)prop), *this);
632 else
634 string tmp = "cannot get property value, view:"+getId()+", parent:"+parentGroup->getId();
635 nlinfo(tmp.c_str());
636 return false;
640 if( _Type == SheetType_SBrick || _Type == SheetType_SPhraseId || _Type == SheetType_SPhrase || _Type == SheetType_Macro )
642 prop = (char*) xmlGetProp( cur, (xmlChar*)"is_shortcut" );
643 if (prop) _ShortCut= convertBool(prop);
646 // _OtherHandItemFilter
647 prop= (char*) xmlGetProp( cur, (xmlChar*)"other_hand_slot" );
648 if(prop)
650 _OptString= (const char*)prop;
651 // Fill the Pointer in setupInit() at first updateCoords() call...
654 // _Grayed
655 prop = (char*) xmlGetProp( cur, (xmlChar*)"grayed" );
656 if(prop) _Grayed= CInterfaceElement::convertBool(prop);
658 // Draw the slot ?
659 _DrawSlot = true;
660 prop = (char*) xmlGetProp( cur, (xmlChar*)"slot" );
661 if(prop) _DrawSlot= CInterfaceElement::convertBool(prop);
664 _HpBuffIcon = "ico_heal.tga";
665 prop = (char*) xmlGetProp( cur, (xmlChar*)"hp_buff_icon" );
666 if (prop) _HpBuffIcon = string((const char *)prop);
668 _SapBuffIcon = "ico_sap.tga";
669 prop = (char*) xmlGetProp( cur, (xmlChar*)"sap_buff_icon" );
670 if (prop) _SapBuffIcon = string((const char *)prop);
672 _StaBuffIcon = "ico_stamina.tga";
673 prop = (char*) xmlGetProp( cur, (xmlChar*)"sta_buff_icon" );
674 if (prop) _StaBuffIcon = string((const char *)prop);
676 _FocusBuffIcon = "ico_focus.tga";
677 prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
678 if (prop) _FocusBuffIcon = string((const char *)prop);
680 updateActualType();
681 // Init size for Type
682 initSheetSize();
683 return true;
686 // ----------------------------------------------------------------------------
687 void CDBCtrlSheet::initSheet(const std::string &dbBranchId, const CCtrlSheetInfo &ctrlInfo)
689 H_AUTO ( RZ_CDBCtrlSheet_initSheet )
691 nlassert((ctrlInfo._Type == SheetType_Macro) || !dbBranchId.empty());
692 nlassert((ctrlInfo._Type == SheetType_Macro) || !_Id.empty());
694 // init
695 *static_cast<CCtrlSheetInfo*>(this)= ctrlInfo;
697 // link to the branch
698 if (ctrlInfo._Type != SheetType_Macro)
700 setSheet(dbBranchId);
702 // get over for spell
703 CInterfaceManager *pIM = CInterfaceManager::getInstance();
704 _TextureIdOver = CViewRenderer::getInstance()->getTextureIdFromName ("w_slot_spell_over.tga");
707 // Init size.
708 initSheetSize();
711 // ----------------------------------------------------------------------------
712 void CDBCtrlSheet::initSheetFast( const std::string &dbParentBranchId, int sheetNum, int slotNum,
713 const CCtrlSheetInfo &ctrlInfo )
715 H_AUTO ( RZ_CDBCtrlSheet_initSheetFast )
717 nlassert((ctrlInfo._Type == SheetType_Macro) || (!dbParentBranchId.empty()));
718 nlassert((ctrlInfo._Type == SheetType_Macro) || (!_Id.empty()));
720 // init
721 *static_cast<CCtrlSheetInfo*>(this)= ctrlInfo;
723 // link to the branch
724 if (ctrlInfo._Type != SheetType_Macro)
726 setSheetFast( dbParentBranchId, sheetNum, slotNum );
728 // get over for spell
729 CInterfaceManager *pIM = CInterfaceManager::getInstance();
730 _TextureIdOver = CViewRenderer::getInstance()->getTextureIdFromName ("w_slot_spell_over.tga");
733 // Init size.
734 initSheetSize();
737 // ----------------------------------------------------------------------------
738 std::string CDBCtrlSheet::getSheet() const
740 return _DbBranchName;
744 // ***************************************************************************
745 void CDBCtrlSheet::setSheet (const std::string &dbBranchId)
747 // link to the DBBranch
748 _DbBranchName= dbBranchId;
750 // Compute the index in DB
751 _IndexInDB= 0;
752 _SecondIndexInDB= 0;
753 string::size_type pos= dbBranchId.rfind(':');
754 if(pos!=string::npos)
756 // get the number after the ':'
757 fromString(dbBranchId.substr(pos+1), _IndexInDB);
758 // try to get the _SecondIndexInDB.
759 if(pos>0)
761 _SecondIndexInDB= getInventorySlot(dbBranchId);
765 // set sheet DB links
766 setupSheetDbLinks();
770 // ***************************************************************************
771 void CDBCtrlSheet::setSheetFast( const std::string &dbParentBranchId, int sheetNum, int slotNum )
773 H_AUTO ( RZ_CDBCtrlSheet_setSheet )
775 // link to the DBBranch
776 _DbBranchName = dbParentBranchId + ":" + NLMISC::toString(sheetNum);
778 // Set the index in DB.
779 _IndexInDB = sheetNum;
780 _SecondIndexInDB = slotNum;
782 // set sheet DB links
783 setupSheetDbLinks();
787 // ***************************************************************************
788 void CDBCtrlSheet::setupSheetDbLinks ()
790 H_AUTO ( RZ_CDBCtrlSheet_setSheet )
792 CInterfaceManager *pIM= CInterfaceManager::getInstance();
794 // link to the DBBranch (NB: none for macros)
795 CCDBNodeBranch *dbBranch = NLGUI::CDBManager::getInstance()->getDbBranch( _DbBranchName );
796 //nlassert(dbBranch || _DbBranchName.empty());
798 // link if possible with the database, else dummy link to the interface
799 switch( _Type )
801 case SheetType_Mission:
803 // LastSheetId is used as last mission text (mission text which is a server string id)
804 _LastSheetId = 0;
806 // Mission icon use _SheetId -> gives the sheet that contains the name of the icon texture
807 if( !_SheetId.link( dbBranch, _DbBranchName+":ICON", pIM->_DB_UI_DUMMY_SHEET ) )
808 nlwarning ("ERROR !!! Cannot find mission icon");
810 _Quality.link( pIM->_DB_UI_DUMMY_QUALITY );
811 break;
813 case SheetType_SPhraseId:
815 _SheetId.link( dbBranch, _DbBranchName+":PHRASE", pIM->_DB_UI_DUMMY_PHRASE );
816 break;
818 case SheetType_GuildFlag:
819 case SheetType_ElevatorDestination:
821 // LastSheetId is used as last guild name (guild name which is a server string id)
822 _LastSheetId = 0;
824 // Guild name use _SheetId
825 if( !_SheetId.link( dbBranch, _DbBranchName+":NAME", pIM->_DB_UI_DUMMY_SHEET ) )
826 nlwarning ("ERROR !!! Cannot find guild name : %s", (_DbBranchName+":NAME").c_str());
828 // Guild icon use _Quality
829 if( !_Quality.link( dbBranch, _DbBranchName+":ICON", pIM->_DB_UI_DUMMY_QUALITY ) )
830 nlwarning ("ERROR !!! Cannot find guild icon: %s", (_DbBranchName+":ICON").c_str());
832 // MacroID is used as the last guild icon
833 _MacroID = 0;
834 break;
836 default:
838 // sheet
839 _SheetId.link( dbBranch, _DbBranchName+":SHEET", pIM->_DB_UI_DUMMY_SHEET );
841 if (_HasTradeSlotType)
842 _TradeSlotType.link( dbBranch, _DbBranchName+":SLOT_TYPE", pIM->_DB_UI_DUMMY_SLOT_TYPE );
844 updateActualType();
846 if(_ActualType == SheetType_Item || _ActualType == SheetType_Pact)
848 // quality
849 if (_UseQuality)
850 _Quality.link( dbBranch, _DbBranchName+":QUALITY", pIM->_DB_UI_DUMMY_QUALITY );
851 else
852 _Quality.link(pIM->_DB_UI_DUMMY_QUALITY);
854 // quantity
855 if(_ActualType == SheetType_Item)
857 if (_UseQuantity)
858 _Quantity.link( dbBranch, _DbBranchName+":QUANTITY", pIM->_DB_UI_DUMMY_QUANTITY );
859 else
860 _Quantity.link( pIM->_DB_UI_DUMMY_QUANTITY );
862 else if(_ActualType == SheetType_Pact)
863 _UseQuantity = false;
865 // Misc Item
866 if(_ActualType == SheetType_Item)
868 // Link to worned state if possible
869 _Worned.link( dbBranch, _DbBranchName+":WORNED", pIM->_DB_UI_DUMMY_WORNED );
871 // Link to _PrerequisitValid state if possible
872 _PrerequisitValid.link( dbBranch, _DbBranchName+":PREREQUISIT_VALID", pIM->_DB_UI_DUMMY_PREREQUISIT_VALID );
877 break;
879 } // switch( _Type )
881 // Link to NameId if possible (if item, else will link to UI:DUMMY:NAMEID).
882 _NameId.link( dbBranch, _DbBranchName+":NAMEID", pIM->_DB_UI_DUMMY_NAMEID );
884 // Link to Enchant if possible (if item, else will link to UI:DUMMY:ENCHANT).
885 _Enchant.link( dbBranch, _DbBranchName+":ENCHANT", pIM->_DB_UI_DUMMY_ENCHANT );
887 if(dbBranch)
889 // Link to UserColor if possible. else will link NULL.
890 _UserColor = dbBranch->getLeaf( _DbBranchName+":USER_COLOR", false );
892 // Link to item RM types if possible, else will link NULL
893 _ItemRMClassType= dbBranch->getLeaf( _DbBranchName+":RM_CLASS_TYPE", false );
894 _ItemRMFaberStatType= dbBranch->getLeaf( _DbBranchName+":RM_FABER_STAT_TYPE", false );
896 // If auto grayed, link to "LOCKED" if possible
897 if(_AutoGrayed)
898 _GrayedLink= dbBranch->getLeaf( _DbBranchName+":LOCKED", false );
899 else
900 _GrayedLink= NULL;
902 else
904 _UserColor= NULL;
905 _ItemRMClassType= NULL;
906 _ItemRMFaberStatType= NULL;
907 _GrayedLink= NULL;
910 // force reset of cache
911 _NeedSetup= true;
915 // ***************************************************************************
916 // determine the inventory slot from the database branch id
917 // return 0 if no match found
918 uint CDBCtrlSheet::getInventorySlot( const string &dbBranchId )
920 // skip the SERVER: or LOCAL:
921 string::size_type pos = dbBranchId.find( ":" );
922 if(pos==string::npos)
923 return 0;
924 const char *szName = dbBranchId.c_str() + pos+1;
925 const char *szName2;
927 // fast selection according to first letters
928 switch( szName[0] )
930 case 'E':
931 if( strncmp( "EXCHANGE:", szName, 9 ) )
932 break;
933 szName2 = &szName[9];
934 if( !strncmp( "GIVE", szName2, 4 ) )
935 return INVENTORIES::exchange;
936 if( !strncmp( "RECEIVE", szName2, 7 ) )
937 return INVENTORIES::exchange_proposition;
938 break;
939 case 'G':
940 if( !strncmp( "GUILD:INVENTORY", szName, 15 ) )
941 return INVENTORIES::guild;
942 break;
943 case 'I':
944 if( strncmp( "INVENTORY:", szName, 10 ) )
945 break;
946 szName2 = &szName[10];
947 switch( szName2[0] )
949 case 'B':
950 if( !strncmp( "BAG", szName2, 3 ) )
951 return INVENTORIES::bag;
952 break;
953 case 'P':
954 nlctassert(MAX_INVENTORY_ANIMAL==7);
955 if( strncmp( "PACK_ANIMAL", szName2, 11 ) )
956 break;
957 switch( szName2[11] )
959 case '0':
960 return INVENTORIES::pet_animal1;
961 case '1':
962 return INVENTORIES::pet_animal2;
963 case '2':
964 return INVENTORIES::pet_animal3;
965 case '3':
966 return INVENTORIES::pet_animal4;
967 case '4':
968 return INVENTORIES::pet_animal5;
969 case '5':
970 return INVENTORIES::pet_animal6;
971 case '6':
972 return INVENTORIES::pet_animal7;
973 default:
974 break;
976 break;
977 case 'R':
978 if( !strncmp( "ROOM", szName2, 4 ) )
979 return INVENTORIES::player_room;
980 break;
981 case 'T':
982 if( !strncmp( "TEMP", szName2, 4 ) )
983 return INVENTORIES::temporary;
984 break;
985 default:
986 break;
988 default:
989 break;
991 return 0;
994 // ----------------------------------------------------------------------------
995 void CDBCtrlSheet::initSheetSize()
997 CInterfaceManager *pIM = CInterfaceManager::getInstance();
998 CViewRenderer &rVR = *CViewRenderer::getInstance();
999 // If the user type is auto, then select always item slot.
1000 if(_Type==SheetType_Auto)
1002 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_item.tga");
1003 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_item_selected.tga");
1005 // Else select from actual type.
1006 else
1008 switch(_ActualType)
1010 case SheetType_Item:
1011 case SheetType_Pact:
1012 case SheetType_Mission:
1013 case SheetType_OutpostBuilding:
1014 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_item.tga");
1015 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_item_selected.tga");
1016 break;
1017 case SheetType_Macro:
1018 case SheetType_SBrick:
1019 case SheetType_SPhraseId:
1020 case SheetType_SPhrase:
1021 if(_BrickOverable)
1023 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_spell.tga");
1024 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_spell_selected.tga");
1026 else
1028 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_brick.tga");
1029 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_brick_selected.tga");
1031 break;
1032 case SheetType_ElevatorDestination:
1033 case SheetType_GuildFlag:
1034 _DispSlotBmpId = rVR.getTextureIdFromName ("w_slot_blason.tga");
1035 _DispSelSlotId = rVR.getTextureIdFromName ("w_slot_blason_over.tga");
1036 break;
1037 default:
1038 break;
1041 rVR.getTextureSizeFromId (_DispSlotBmpId, _W, _H);
1044 // ----------------------------------------------------------------------------
1045 void CDBCtrlSheet::updateCoords ()
1047 if (getActive())
1049 if (_Type != CCtrlSheetInfo::SheetType_Macro)
1051 if (!_SetupInit) setupInit();
1053 if (_LastSheetId != _SheetId.getSInt32())
1055 updateActualType();
1059 switch(_ActualType)
1061 case CCtrlSheetInfo::SheetType_Item: setupItem(); break;
1062 case CCtrlSheetInfo::SheetType_Pact: setupPact(); break;
1063 case CCtrlSheetInfo::SheetType_SBrick: setupSBrick(); break;
1064 case CCtrlSheetInfo::SheetType_SPhraseId: setupSPhraseId(); break;
1065 case CCtrlSheetInfo::SheetType_SPhrase: setupSPhrase(); break;
1066 case CCtrlSheetInfo::SheetType_Mission: setupMission(); break;
1067 case CCtrlSheetInfo::SheetType_OutpostBuilding: setupOutpostBuilding(); break;
1068 default: break;
1071 if (_Type != CCtrlSheetInfo::SheetType_Macro)
1073 _LastSheetId = _SheetId.getSInt32();
1076 CInterfaceElement::updateCoords();
1079 // ----------------------------------------------------------------------------
1080 void CDBCtrlSheet::updateIconSize()
1082 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1083 CViewRenderer &rVR = *CViewRenderer::getInstance();
1084 if (_DispSheetBmpId != -1)
1086 rVR.getTextureSizeFromId(_DispSheetBmpId, _IconW, _IconH);
1088 else if (_DispBackBmpId != -1)
1090 rVR.getTextureSizeFromId(_DispBackBmpId, _IconW, _IconH);
1092 else if (_DispOverBmpId != -1)
1094 rVR.getTextureSizeFromId(_DispOverBmpId, _IconW, _IconH);
1096 else if (_DispOver2BmpId != -1)
1098 rVR.getTextureSizeFromId(_DispOver2BmpId, _IconW, _IconH);
1100 else
1102 _IconW = _IconH = 0;
1106 // ***************************************************************************
1107 void CDBCtrlSheet::clearIconBuffs()
1109 _EnchantIcons.clear();
1110 _BuffIcons.clear();
1113 // ***************************************************************************
1114 void CDBCtrlSheet::infoReceived()
1116 if (!_ItemSheet)
1118 clearIconBuffs();
1119 return;
1122 const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
1123 if (itemInfo == NULL)
1125 // schedule for recheck on next draw()
1126 _ItemInfoChanged = true;
1127 return;
1130 clearIconBuffs();
1132 // crystallized spell
1134 CViewRenderer &rVR = *CViewRenderer::getInstance();
1135 CSBrickManager *pBM= CSBrickManager::getInstance();
1136 for(uint i=0; i<itemInfo->Enchantment.Bricks.size(); ++i)
1138 const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
1139 if (brick)
1141 if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
1143 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
1144 rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1146 else if (brick->isRoot())
1148 // there should be single root icon and it should be first one
1149 _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
1150 rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
1156 // buff icons
1158 CViewRenderer &rVR = *CViewRenderer::getInstance();
1160 if (itemInfo->HpBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_HpBuffIcon)));
1161 if (itemInfo->SapBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_SapBuffIcon)));
1162 if (itemInfo->StaBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_StaBuffIcon)));
1163 if (itemInfo->FocusBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_FocusBuffIcon)));
1165 // update sizes
1166 for(uint i = 0; i < _BuffIcons.size(); ++i)
1168 rVR.getTextureSizeFromId(_BuffIcons[i].TextureId, _BuffIcons[i].IconW, _BuffIcons[i].IconH);
1173 // ***************************************************************************
1174 void CDBCtrlSheet::setupPact()
1176 sint32 sheet = _SheetId.getSInt32();
1177 // If this is the same sheet, need to resetup
1178 if (_LastSheetId != sheet || _NeedSetup)
1180 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1181 CViewRenderer &rVR = *CViewRenderer::getInstance();
1183 _LastSheetId = sheet;
1184 CSheetId sheetId(sheet);
1185 CEntitySheet *pES = SheetMngr.get (sheetId);
1186 if ((pES != NULL) && (pES->type() == CEntitySheet::PACT))
1188 CPactSheet *pPS = (CPactSheet*)pES;
1189 _DispSheetBmpId = rVR.getTextureIdFromName (pPS->Icon);
1190 _DispBackBmpId = rVR.getTextureIdFromName (pPS->IconBackground);
1191 _DispOverBmpId = -1;
1192 _DispOver2BmpId = -1;
1193 updateIconSize();
1194 if (_UseQuality)
1195 _DispQuality = _Quality.getSInt32();
1196 else
1197 _DispQuality = -1;
1199 else
1201 resetAllTexIDs();
1204 else
1206 // update quality
1207 if(_UseQuality)
1208 _DispQuality = _Quality.getSInt32();
1209 else
1210 _DispQuality = -1;
1214 // ***************************************************************************
1215 bool CDBCtrlSheet::useItemInfoForFamily(ITEMFAMILY::EItemFamily family) const
1217 return family == ITEMFAMILY::CRYSTALLIZED_SPELL
1218 || family == ITEMFAMILY::JEWELRY
1219 || family == ITEMFAMILY::ARMOR
1220 || family == ITEMFAMILY::MELEE_WEAPON
1221 || family == ITEMFAMILY::RANGE_WEAPON
1222 || family == ITEMFAMILY::SHIELD
1223 || family == ITEMFAMILY::CRAFTING_TOOL
1224 || family == ITEMFAMILY::HARVEST_TOOL
1225 || family == ITEMFAMILY::TAMING_TOOL
1226 || family == ITEMFAMILY::TRAINING_TOOL;
1229 // ***************************************************************************
1230 void CDBCtrlSheet::setupItem ()
1232 CInterfaceManager *pIM= CInterfaceManager::getInstance();
1234 sint32 sheet = _SheetId.getSInt32();
1236 // If this is the same sheet, need to resetup
1237 if (_LastSheetId != sheet || _NeedSetup)
1239 CViewRenderer &rVR = *CViewRenderer::getInstance();
1241 _NeedSetup= false;
1242 _LastSheetId = sheet;
1243 CSheetId sheetId(sheet);
1244 CEntitySheet *pES = SheetMngr.get (sheetId);
1245 if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM))
1247 _ItemSheet = (CItemSheet*)pES;
1249 // Display the item quality?
1250 _DisplayItemQuality= _UseQuality &&
1251 _ItemSheet->Family != ITEMFAMILY::COSMETIC &&
1252 _ItemSheet->Family != ITEMFAMILY::TELEPORT &&
1253 _ItemSheet->Family != ITEMFAMILY::SERVICE
1256 _DispSheetBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconMain());
1257 // if file not found or empty, replace by default icon
1258 if( _DispSheetBmpId == -1)
1259 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1260 if(_ForceItemBackGroundGeneric)
1261 _DispBackBmpId = rVR.getTextureIdFromName ("BK_generic.tga");
1262 else
1263 _DispBackBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconBack());
1264 _DispOverBmpId = rVR.getTextureIdFromName (_ItemSheet->getIconOver());
1265 _DispOver2BmpId = rVR.getTextureIdFromName (_ItemSheet->getIconOver2());
1266 _PackedArmourColor = 0;
1267 _ArmourColorFromDB= false;
1268 _ArmourColorBmpOk= false;
1269 // if icon is an armour, and no over texture is given, build its name
1270 if (_ItemSheet->Family == ITEMFAMILY::ARMOR)
1272 sint col = _ItemSheet->Color;
1273 if (col == -1) // user color wanted ?
1275 col = getItemColor(); // read color from db
1276 // If the DB exist
1277 if(_UserColor)
1278 _ArmourColorFromDB= true;
1280 updateArmourColor(col);
1283 updateIconSize();
1285 // Icon Colors
1286 _IconBackColor= _ItemSheet->IconBackColor;
1287 _IconColor= _ItemSheet->IconColor;
1288 _IconOverColor= _ItemSheet->IconOverColor;
1289 _IconOver2Color= _ItemSheet->IconOver2Color;
1291 // Setup Quantity
1292 if (_UseQuantity)
1294 // is this item stackable? more than one.
1295 _Stackable= _ItemSheet->Stackable;
1297 if (getStackable() > 1)
1299 if (_ReadQuantityFromSheet)
1301 _DispQuantity = getStackable();
1303 else
1305 // display the stack quantity
1306 _DispQuantity = _Quantity.getSInt32();
1309 else
1310 // do not display any number
1311 _DispQuantity = -1;
1313 else _DispQuantity = -1;
1315 // Setup quality
1316 if(_DisplayItemQuality)
1318 _DispQuality= _Quality.getSInt32();
1320 else
1322 _DispQuality= -1;
1325 // special icon text
1326 if( _NeedSetup || _ItemSheet->getIconText() != _OptString )
1328 // compute from OptString. Allow only 1 line and 4 chars
1329 _OptString= _ItemSheet->getIconText();
1330 // Display Top Left
1331 setupCharBitmaps(40, 1, 6, true);
1334 // Special Item requirement
1335 updateItemCharacRequirement(_LastSheetId);
1337 // update item info markers
1338 _ItemInfoChanged = true;
1340 else
1342 resetAllTexIDs();
1345 // must update dispNumber for good quantity/quality.
1346 else
1348 // update quantity
1349 if (getStackable() > 1)
1351 if (_ReadQuantityFromSheet)
1353 _DispQuantity = getStackable();
1355 else
1357 _DispQuantity = _Quantity.getSInt32();
1361 // update quality. NB: if quality change, the must updateItemCharacRequirement
1362 if(_DisplayItemQuality)
1364 sint32 newQuality= _Quality.getSInt32();
1365 if(newQuality!=_DispQuality)
1367 _DispQuality= newQuality;
1368 updateItemCharacRequirement(_LastSheetId);
1371 else
1373 _DispQuality= -1;
1376 // update armour color (if USER_COLOR db change comes after SHEET change)
1377 if(_ArmourColorFromDB && _UserColor)
1379 // If the DB has changed
1380 if(_UserColor->getValue32() != _ArmourColorIndex)
1382 updateArmourColor((sint8)_UserColor->getValue32());
1387 // at each frame, must test for grayed.
1388 if(_AutoGrayed)
1390 if(_GrayedLink)
1392 // gray if not 0
1393 _Grayed= _GrayedLink->getValue32()!=0;
1395 else
1396 _Grayed= false;
1399 // at each frame, must test for Redifyed (player carac does not met item requirement)
1400 _Useable = _PrerequisitValid.getBool();
1402 _Useable= pIM->isItemCaracRequirementMet(_ItemCaracReqType, _ItemCaracReqValue);
1404 if (_Useable && _ItemSheet != NULL)
1406 if (_ItemSheet->RequiredCharac != CHARACTERISTICS::Unknown && _ItemSheet->RequiredCharacLevel>0)
1407 _Useable= pIM->isItemCaracRequirementMet(_ItemSheet->RequiredCharac, _ItemSheet->RequiredCharacLevel);
1409 if (_Useable && _ItemSheet->RequiredSkill != SKILLS::unknown && _ItemSheet->RequiredSkillLevel > 0)
1410 _Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
1414 // at each frame, update item info icon if changed
1415 if (_ItemInfoChanged)
1417 _ItemInfoChanged = false;
1418 setupItemInfoWaiter();
1423 // ***************************************************************************
1424 void CDBCtrlSheet::updateItemCharacRequirement(sint32 sheet)
1426 CSheetId sheetId(sheet);
1427 CEntitySheet *pES = SheetMngr.get (sheetId);
1428 if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM) && _Quality.getNodePtr())
1430 CItemSheet *pIS = (CItemSheet*)pES;
1431 _ItemCaracReqType= CHARACTERISTICS::Unknown;
1432 _ItemCaracReqValue= 0;
1433 float tmpVal;
1434 if(pIS->hasCharacRequirement(_Quality.getSInt32(), _ItemCaracReqType, tmpVal))
1435 _ItemCaracReqValue= (sint32)floor(tmpVal);
1440 // ***************************************************************************
1441 void CDBCtrlSheet::setupMacro()
1443 if (!_NeedSetup) return;
1445 // compute from OptString
1446 setupCharBitmaps(26, 4, 5);
1448 _NeedSetup = false;
1453 // ***************************************************************************
1454 void CDBCtrlSheet::setupMission()
1456 sint32 currIcon = _SheetId.getSInt32();
1457 if (_LastSheetId != currIcon || _NeedSetup)
1459 _LastSheetId = currIcon;
1460 _NeedSetup = false;
1462 CEntitySheet *pES = SheetMngr.get(CSheetId(currIcon));
1463 if (pES == NULL) return;
1464 if (pES->Type != CEntitySheet::MISSION_ICON) return;
1465 CMissionIconSheet *pMIS = (CMissionIconSheet*)pES;
1467 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1468 CViewRenderer &rVR = *CViewRenderer::getInstance();
1470 _DispBackBmpId = rVR.getTextureIdFromName(pMIS->MainIconBg);
1471 _DispSheetBmpId = rVR.getTextureIdFromName(pMIS->MainIconFg);
1473 // Display a '?' only if not 0.
1474 if ((_DispBackBmpId == -1) && (currIcon != 0))
1476 _DispBackBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1481 // ***************************************************************************
1482 void CDBCtrlSheet::setupGuildFlag ()
1484 // Find the guild name
1485 string usGuildName;
1486 sint32 nGuildName = _SheetId.getSInt32();
1487 if (_LastSheetId != nGuildName || _NeedSetup)
1489 CStringManagerClient *pSMC = CStringManagerClient::instance();
1490 bool bValid = pSMC->getDynString (nGuildName, usGuildName);
1491 if (bValid)
1492 _NeedSetup = false;
1495 uint64 nGuildIcon;
1496 nGuildIcon = _Quality.getSInt64();
1499 _UseGuildIcon = ((nGuildIcon>>59)&1)!=0; // 1 bits en pos 59
1500 if (_UseGuildIcon)
1502 _GuildIcon = (uint32)(nGuildIcon&0xffffffff); // 32 bits en pos 0
1504 else
1506 sint8 nGuildBack = (sint8)(nGuildIcon&15); // 4 bits en pos 0
1507 sint8 nGuildSymbol = (sint8)((nGuildIcon>>4)&63); // 6 bits en pos 4
1508 sint8 nGuildInvert = (sint8)((nGuildIcon>>10)&1); // 1 bit en pos 10
1509 uint8 nGuildColBackR = (uint8)((nGuildIcon>>11)&255); // 8 bits en pos 11
1510 uint8 nGuildColBackG = (uint8)((nGuildIcon>>19)&255); // 8 bits en pos 19
1511 uint8 nGuildColBackB = (uint8)((nGuildIcon>>27)&255); // 8 bits en pos 27
1512 uint8 nGuildColSymbR = (uint8)((nGuildIcon>>35)&255); // 8 bits en pos 35
1513 uint8 nGuildColSymbG = (uint8)((nGuildIcon>>43)&255); // 8 bits en pos 43
1514 uint8 nGuildColSymbB = (uint8)((nGuildIcon>>51)&255); // 8 bits en pos 51
1516 sint8 nLastGuildBack = (sint8)(_MacroID&15); // 4 bits en pos 0
1517 sint8 nLastGuildSymbol = (sint8)((_MacroID>>4)&63); // 6 bits en pos 4
1519 NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
1521 if (_GuildMat.empty())
1523 _GuildMat = Driver->createMaterial();
1524 _GuildMat.initUnlit ();
1526 // Alpha blend must use current alpha
1527 _GuildMat.setBlend (true);
1528 _GuildMat.setBlendFunc (UMaterial::one, UMaterial::invsrcalpha);
1530 // Stages 0
1531 _GuildMat.texEnvOpRGB (0, UMaterial::Modulate);
1532 _GuildMat.texEnvArg0RGB (0, UMaterial::Texture, UMaterial::SrcColor);
1533 _GuildMat.texEnvArg1RGB (0, UMaterial::Diffuse, UMaterial::SrcColor);
1534 _GuildMat.texEnvOpAlpha (0, UMaterial::Modulate);
1535 _GuildMat.texEnvArg0Alpha (0, UMaterial::Texture, UMaterial::SrcAlpha);
1536 _GuildMat.texEnvArg1Alpha (0, UMaterial::Diffuse, UMaterial::SrcAlpha);
1538 // This is alpha material, so don't zwrite
1539 _GuildMat.setZWrite (false);
1540 _GuildMat.setBlendFunc (UMaterial::srcalpha, UMaterial::invsrcalpha);
1543 if (nGuildInvert == 0)
1545 // Stages 1
1546 _GuildMat.texEnvOpRGB (1, UMaterial::Modulate);
1547 _GuildMat.texEnvArg0RGB (1, UMaterial::Texture, UMaterial::SrcColor);
1548 _GuildMat.texEnvArg1RGB (1, UMaterial::Previous, UMaterial::SrcColor);
1550 else
1552 // Stages 1
1553 _GuildMat.texEnvOpRGB (1, UMaterial::Add);
1554 _GuildMat.texEnvArg0RGB (1, UMaterial::Texture, UMaterial::InvSrcColor);
1555 _GuildMat.texEnvArg1RGB (1, UMaterial::Previous, UMaterial::SrcColor);
1559 _SheetColor = CRGBA(nGuildColBackR,nGuildColBackG,nGuildColBackB);
1560 _IconColor = CRGBA(nGuildColSymbR,nGuildColSymbG,nGuildColSymbB);
1562 if (nLastGuildBack != nGuildBack)
1564 if (_GuildBack != NULL)
1565 Driver->deleteTextureFile(_GuildBack);
1566 _GuildBack = NULL;
1567 if (nGuildBack > 0)
1569 string txName = toString("Guild_Back_S_%02d.tga", nGuildBack-1);
1570 _GuildBack = Driver->createTextureFile (txName);
1574 if (nLastGuildSymbol != nGuildSymbol)
1576 if (_GuildSymb != NULL)
1577 Driver->deleteTextureFile(_GuildSymb);
1578 _GuildSymb = NULL;
1579 if (nGuildSymbol > 0)
1581 string txName = toString("Guild_Symbol_S_%02d.tga", nGuildSymbol-1);
1582 _GuildSymb = Driver->createTextureFile (txName);
1585 _GuildMat.setTexture(0, _GuildBack);
1586 _GuildMat.setTexture(1, _GuildSymb);
1588 _MacroID = (sint32)(nGuildIcon&1023); // on garde les 10 premiers bits
1593 // ***************************************************************************
1594 void CDBCtrlSheet::setupDisplayAsSBrick(sint32 sheet, sint32 optSheet)
1596 // Setup with the param sheet
1597 CSBrickManager *pBM = CSBrickManager::getInstance();
1598 CViewRenderer &rVR = *CViewRenderer::getInstance();
1600 CSBrickSheet *pBR = pBM->getBrick (CSheetId(sheet));
1601 CSBrickSheet *pBROpt = pBM->getBrick (CSheetId(optSheet));
1602 if (pBR != NULL)
1604 // Get Back and Over.
1605 _DispBackBmpId = rVR.getTextureIdFromName (pBR->getIconBack());
1606 _IconBackColor = pBR->IconBackColor;
1607 _DispOverBmpId = rVR.getTextureIdFromName (pBR->getIconOver());
1608 _IconOverColor = pBR->IconOverColor;
1610 // For phrase display, replace icon and over2 with optional brick
1611 if(pBROpt)
1613 // get the correct icon
1614 bool iconOver2NotSuitableForActionDisplay;
1615 if ( pBM->getSabrinaCom().isMainDisplayIconInOverSlot( CSheetId(optSheet), iconOver2NotSuitableForActionDisplay ) )
1617 _DispSheetBmpId = rVR.getTextureIdFromName (pBROpt->getIconOver());
1618 _IconColor = pBROpt->IconOverColor;
1620 else
1622 _DispSheetBmpId = rVR.getTextureIdFromName (pBROpt->getIcon());
1623 _IconColor = pBROpt->IconColor;
1626 // get the correct over2
1627 if ( iconOver2NotSuitableForActionDisplay )
1629 _DispOver2BmpId = rVR.getTextureIdFromName (pBR->getIconOver2());
1630 _IconOver2Color = pBR->IconOver2Color;
1632 else
1634 _DispOver2BmpId = rVR.getTextureIdFromName (pBROpt->getIconOver2());
1635 _IconOver2Color = pBROpt->IconOver2Color;
1638 else
1640 _DispSheetBmpId = rVR.getTextureIdFromName (pBR->getIcon());
1641 _IconColor = pBR->IconColor;
1642 _DispOver2BmpId = rVR.getTextureIdFromName (pBR->getIconOver2());
1643 _IconOver2Color = pBR->IconOver2Color;
1646 // if file not found or empty, replace by default icon
1647 if( _DispSheetBmpId == -1)
1648 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultBrickTexture);
1649 updateIconSize();
1650 _DispLevel = pBR->Level;
1651 _MustDisplayLevel = pBR->mustDisplayLevel();
1653 else
1655 resetAllTexIDs();
1659 // ***************************************************************************
1660 void CDBCtrlSheet::setupSBrick ()
1662 sint32 sheet = (sint32)_SheetId.getSInt32();
1664 // If this is the same sheet id so no need to resetup
1665 if (_LastSheetId != sheet || _NeedSetup)
1667 _LastSheetId = sheet;
1668 setupDisplayAsSBrick(sheet);
1670 // Reseted.
1671 _NeedSetup= false;
1674 // SBrick support auto grayed. test each frame
1675 if(_AutoGrayed)
1677 if(_GrayedLink)
1679 // gray if not 0
1680 _Grayed= _GrayedLink->getValue32()!=0;
1681 // Reded, if 2
1682 _Useable= _GrayedLink->getValue32()!=2;
1684 else
1685 _Grayed= false;
1689 // ***************************************************************************
1690 void CDBCtrlSheet::setupDisplayAsPhrase(const std::vector<NLMISC::CSheetId> &bricks, const string &phraseName)
1692 CSBrickManager *pBM = CSBrickManager::getInstance();
1694 // Get the best SBrick to display.
1695 CSheetId rootBrickSheetId= bricks[0];
1697 CSheetId bestBrickSheetId= pBM->getSabrinaCom().getPhraseBestDisplayBrick(bricks);
1698 setupDisplayAsSBrick (rootBrickSheetId.asInt(), bestBrickSheetId.asInt() );
1701 // Override background if type is forace extraction/prospection and ecosystem brick is used
1703 BRICK_FAMILIES::TBrickFamily family = pBM->getSabrinaCom().getPhraseForageFamily(bricks);
1704 std::string icon;
1705 switch(family)
1707 case BRICK_FAMILIES::BHFEMA:
1708 case BRICK_FAMILIES::BHFPMA:
1709 icon = "bk_matis_brick.tga";
1710 break;
1711 case BRICK_FAMILIES::BHFEMB:
1712 case BRICK_FAMILIES::BHFPMB:
1713 icon = "bk_fyros_brick.tga";
1714 break;
1715 case BRICK_FAMILIES::BHFEMC:
1716 case BRICK_FAMILIES::BHFPMC:
1717 icon = "bk_zorai_brick.tga";
1718 break;
1719 case BRICK_FAMILIES::BHFEMD:
1720 case BRICK_FAMILIES::BHFPMD:
1721 icon = "bk_tryker_brick.tga";
1722 break;
1723 case BRICK_FAMILIES::BHFEME:
1724 case BRICK_FAMILIES::BHFPME:
1725 icon = "bk_generic_brick.tga";
1726 break;
1727 default:
1728 icon = "";
1729 break;
1731 if (!icon.empty())
1733 CViewRenderer &rVR = *CViewRenderer::getInstance();
1734 _DispBackBmpId = rVR.getTextureIdFromName(icon);
1738 // not so beautiful to display .sphrase name in progression, and in botchat
1739 if(_ActualType==SheetType_SPhraseId)
1741 // Compute the text from the phrase only if needed
1742 // string iconName= phraseName.toString();
1743 const string &iconName = phraseName;
1744 if( _NeedSetup || iconName != _OptString )
1746 // recompute text
1747 _OptString= iconName;
1748 // compute from OptString. Allow only 1 line and 5 chars
1749 setupCharBitmaps(26, 1, 5);
1754 // ***************************************************************************
1755 void CDBCtrlSheet::setupSPhrase()
1757 sint32 sheet = (sint32)_SheetId.getSInt32();
1759 // If this is the same sheet id so no need to resetup
1760 if (_LastSheetId != sheet || _NeedSetup)
1762 _LastSheetId = sheet;
1763 CSPhraseSheet *pSPS = dynamic_cast<CSPhraseSheet*>(SheetMngr.get(CSheetId(sheet)));
1764 if (pSPS && !pSPS->Bricks.empty())
1766 const char *phraseName = STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(CSheetId(sheet));
1767 setupDisplayAsPhrase(pSPS->Bricks, phraseName);
1769 else
1771 resetAllTexIDs();
1774 // Reseted.
1775 _NeedSetup= false;
1778 // SPhrase support auto grayed. test each frame
1779 if(_AutoGrayed)
1781 if(_GrayedLink)
1783 // gray if not 0
1784 _Grayed= _GrayedLink->getValue32()!=0;
1785 // Reded, if 2
1786 _Useable= _GrayedLink->getValue32()!=2;
1788 else
1789 _Grayed= false;
1793 // ***************************************************************************
1794 void CDBCtrlSheet::setupSPhraseId ()
1796 // get the phrase id
1797 sint32 phraseId = getSPhraseId();
1799 // get the phrase Data version, to check if it had changed.
1800 CSPhraseManager *pPM= CSPhraseManager::getInstance();
1801 sint32 phraseVersion= pPM->getPhraseVersion(phraseId);
1803 // If this is the same phrase id and phrase version no need to resetup
1804 if (_NeedSetup || _LastSheetId != phraseId || _LastPhraseVersion!= phraseVersion)
1806 _LastSheetId= phraseId;
1807 _LastPhraseVersion= phraseVersion;
1809 // Empty Slot?
1810 if(phraseId==0)
1812 resetAllTexIDs();
1814 else
1816 // Get the SPhrase.
1817 const CSPhraseCom &phrase= pPM->getPhrase(phraseId);
1818 if(phrase.empty())
1820 resetAllTexIDs();
1822 else
1824 setupDisplayAsPhrase(phrase.Bricks, phrase.Name.toUtf8()); // FIXME: UTF-8 (serial)
1828 // Reseted.
1829 _NeedSetup= false;
1833 // ***************************************************************************
1834 void CDBCtrlSheet::setupOutpostBuilding()
1836 CInterfaceManager *pIM= CInterfaceManager::getInstance();
1838 sint32 sheet = _SheetId.getSInt32();
1839 // If this is the same sheet, need to resetup
1840 if (_LastSheetId != sheet || _NeedSetup)
1842 CViewRenderer &rVR = *CViewRenderer::getInstance();
1844 _NeedSetup= false;
1845 _LastSheetId = sheet;
1846 CSheetId sheetId(sheet);
1847 CEntitySheet *pES = SheetMngr.get (sheetId);
1848 if ((pES != NULL) && (pES->type() == CEntitySheet::OUTPOST_BUILDING))
1850 COutpostBuildingSheet *pOBSheet = (COutpostBuildingSheet*)pES;
1852 _DisplayItemQuality = false;
1854 _DispSheetBmpId = rVR.getTextureIdFromName (pOBSheet->getIconMain());
1855 // if file not found or empty, replace by default icon
1856 if( _DispSheetBmpId == -1)
1857 _DispSheetBmpId = rVR.getSystemTextureId(CViewRenderer::DefaultItemTexture);
1858 if(_ForceItemBackGroundGeneric)
1859 _DispBackBmpId = rVR.getTextureIdFromName ("BK_generic.tga");
1860 else
1861 _DispBackBmpId = rVR.getTextureIdFromName (pOBSheet->getIconBack());
1862 _DispOverBmpId = rVR.getTextureIdFromName (pOBSheet->getIconOver());
1863 _DispOver2BmpId = -1;
1864 _PackedArmourColor = 0;
1865 _ArmourColorFromDB= false;
1866 _ArmourColorBmpOk= false;
1867 updateIconSize();
1869 _DispQuantity = -1;
1870 _DispQuality = -1;
1872 // special icon text
1873 if (pOBSheet->getIconText() != _OptString)
1875 // compute from OptString. Allow only 1 line and 4 chars
1876 _OptString= pOBSheet->getIconText();
1877 // Display Top Left
1878 setupCharBitmaps(40, 1, 6, true);
1881 else
1883 resetAllTexIDs();
1886 // must update dispNumber for good quantity/quality.
1887 else
1889 _DispQuality = -1;
1892 // at each frame, must test for grayed.
1893 if(_AutoGrayed)
1895 if(_GrayedLink)
1897 // gray if not 0
1898 _Grayed= _GrayedLink->getValue32()!=0;
1900 else
1901 _Grayed= false;
1905 // ***************************************************************************
1906 sint32 CDBCtrlSheet::getSPhraseId() const
1908 if(_SheetId.getNodePtr())
1909 return (sint32)_SheetId.getSInt32();
1910 else
1911 return 0;
1914 // ***************************************************************************
1915 void CDBCtrlSheet::resetCharBitmaps()
1917 _CharBitmaps.clear();
1920 // ***************************************************************************
1921 void CDBCtrlSheet::setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar, bool topDown)
1923 // Use the optString for the Macro name
1924 _OptString = toLowerAscii(_OptString);
1925 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1926 CViewRenderer &rVR = *CViewRenderer::getInstance();
1928 _CharBitmaps.clear();
1930 if(maxLine<=0)
1931 return;
1933 uint h = rVR.getTypoTextureH('a');
1934 sint lineNb = 0;
1935 sint curLineSize = 0;
1936 uint i;
1937 uint xChar= 0;
1938 for (i = 0; i < _OptString.size(); ++i)
1940 char c = _OptString[i];
1941 sint32 w = rVR.getTypoTextureW(c);
1942 if ((curLineSize + w) > maxW || (sint32)xChar>=maxWChar)
1944 lineNb ++;
1945 if (lineNb == maxLine) break;
1946 curLineSize = 0;
1947 xChar = 0;
1949 sint32 id = rVR.getTypoTextureId(c);
1950 if (id != -1)
1952 CCharBitmap bmp;
1953 bmp.X= curLineSize;
1954 bmp.Y= lineNb;
1955 bmp.Id= id;
1956 _CharBitmaps.push_back(bmp);
1958 curLineSize += w;
1959 ++xChar;
1962 if (lineNb == maxLine) lineNb = maxLine-1;
1964 for (i = 0; i < _CharBitmaps.size(); ++i)
1966 _CharBitmaps[i].Y = (lineNb - _CharBitmaps[i].Y)*h;
1969 // if topDown, revert Y
1970 if (topDown)
1972 for (i = 0; i < _CharBitmaps.size(); ++i)
1974 _CharBitmaps[i].Y = _IconH - _CharBitmaps[i].Y - h;
1979 // ***************************************************************************
1980 void CDBCtrlSheet::displayCharBitmaps(sint32 rdrLayer, sint32 x, sint32 y, CRGBA color)
1982 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1983 CViewRenderer &rVR = *CViewRenderer::getInstance();
1985 for (uint i = 0; i < _CharBitmaps.size(); ++i)
1987 rVR.draw11RotFlipBitmap (rdrLayer, x+_CharBitmaps[i].X, y+_CharBitmaps[i].Y, 0, false,
1988 _CharBitmaps[i].Id, color);
1993 // ***************************************************************************
1994 void CDBCtrlSheet::draw()
1996 H_AUTO( RZ_Interface_CDBCtrlSheet_draw )
1998 CInterfaceManager *pIM = CInterfaceManager::getInstance();
1999 CViewRenderer &rVR = *CViewRenderer::getInstance();
2001 if (_Type != SheetType_Macro)
2003 if (_LastSheetId != _SheetId.getSInt32())
2005 updateActualType();
2006 _LastSheetId = _SheetId.getSInt32();
2007 _NeedSetup= true;
2011 // Manage over for brick
2012 if( _BrickOverable && (isMacro() || isSBrickOrSPhraseId() || isSPhrase()) )
2014 const vector<CCtrlBase*> &rVB = CWidgetManager::getInstance()->getCtrlsUnderPointer ();
2015 uint32 i;
2016 for (i = 0; i < rVB.size(); ++i)
2017 if (rVB[i] == this)
2019 _Over = true;
2020 break;
2022 if (i == rVB.size())
2023 _Over = false;
2027 // Display slot
2028 if (_DrawSlot)
2029 rVR.draw11RotFlipBitmap (_RenderLayer, _XReal, _YReal, 0, false, _DispSlotBmpId, CWidgetManager::getInstance()->getGlobalColorForContent());
2031 // Drag'N'Drop : display the selected slot bitmap if this slot accept the currently dragged element
2032 _CanDrop = false;
2033 if (_AHOnCanDrop != NULL)
2034 if ((CWidgetManager::getInstance()->getCapturePointerLeft() != NULL) && (CWidgetManager::getInstance()->getCapturePointerLeft() != this))
2036 if ((CWidgetManager::getInstance()->getPointer()->getX() >= _XReal) &&
2037 (CWidgetManager::getInstance()->getPointer()->getX() < (_XReal + _WReal))&&
2038 (CWidgetManager::getInstance()->getPointer()->getY() > _YReal) &&
2039 (CWidgetManager::getInstance()->getPointer()->getY() <= (_YReal+ _HReal)))
2040 if (CWidgetManager::getInstance()->getCurrentWindowUnder() == CWidgetManager::getInstance()->getWindow(this))
2042 CDBCtrlSheet *pCSSrc = dynamic_cast<CDBCtrlSheet*>(CWidgetManager::getInstance()->getCapturePointerLeft());
2043 if ((pCSSrc != NULL) && pCSSrc->isDragged())
2045 string params = string("src=") + pCSSrc->getId();
2046 if (!_AHCanDropParams.empty())
2048 if ( CAHManager::getInstance()->getAHName(_AHOnCanDrop) == "lua")
2050 params = _AHCanDropParams;
2051 strFindReplace(params, "%src", pCSSrc->getId());
2053 else
2055 string sTmp = _AHCanDropParams;
2056 params = sTmp + "|" + params;
2059 CAHManager::getInstance()->runActionHandler (_AHOnCanDrop, this, params);
2064 drawSheet (_XReal+1, _YReal+1, isDragged() );
2066 // Draw the selection after the sheet. Important for spells because selection border is same size as spell square
2067 if (_CanDrop)
2069 // decal layer because must drawn after Items/Brick in DXTC
2070 rVR.draw11RotFlipBitmap (_RenderLayer+1, _XReal, _YReal, 0, false, _DispSelSlotId, CWidgetManager::getInstance()->getGlobalColorForContent());
2073 if (_RegenTickRange.EndTick != _RegenTickRange.StartTick)
2075 if (!_LastSheetId)
2077 _RegenTickRange = CTickRange();
2078 if (_RegenText)
2080 delete _RegenText;
2081 _RegenText = NULL;
2082 _RegenTextValue = 0;
2085 else
2087 // Render regen texture in overlay, in clock wise order
2088 float amount = (LastGameCycle - _RegenTickRange.StartTick) / float(_RegenTickRange.EndTick - _RegenTickRange.StartTick);
2089 clamp(amount, 0.f, 1.f);
2091 sint32 texWidth;
2092 sint32 texHeight;
2093 uint32 frontTex = rVR.getSystemTextureId(CViewRenderer::RegenTexture);
2094 uint32 backTex = rVR.getSystemTextureId(CViewRenderer::RegenBackTexture);
2096 rVR.getTextureSizeFromId(frontTex, texWidth, texHeight);
2097 CQuadUV regenTris[5];
2098 uint numTris = buildPie(regenTris, 0.f, amount, texWidth);
2099 nlassert(numTris <= sizeofarray(regenTris));
2100 for (uint tri = 0; tri < numTris; ++tri)
2102 rVR.drawQuad(_RenderLayer + 1, regenTris[tri], frontTex, CRGBA::White, false);
2104 numTris = buildPie(regenTris, amount, 1.f, texWidth);
2105 nlassert(numTris <= sizeofarray(regenTris));
2106 for (uint tri = 0; tri < numTris; ++tri)
2108 rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false);
2111 if (!_RegenText) {
2112 _RegenText = new CViewText(CViewBase::TCtorParam());
2113 _RegenText->setId(getId() + ":regen");
2114 _RegenText->setParent(_Parent);
2115 _RegenText->setOverflowText(std::string());
2116 _RegenText->setModulateGlobalColor(false);
2117 _RegenText->setMultiLine(false);
2118 _RegenText->setTextMode(CViewText::ClipWord);
2119 _RegenText->setFontSizing("0", "0");
2120 // TODO: font size / color hardcoded.
2121 _RegenText->setFontSize(8);
2122 _RegenText->setColor(CRGBA::White);
2123 _RegenText->setShadow(true);
2124 _RegenText->setActive(true);
2125 _RegenText->updateTextContext();
2128 // TODO: ticks in second hardcoded
2129 uint32 nextValue = _RegenTickRange.EndTick > LastGameCycle ? (_RegenTickRange.EndTick - LastGameCycle) / 10 : 0;
2130 if (_RegenTextValue != nextValue)
2132 _RegenTextValue = nextValue;
2133 _RegenText->setText(toString("%d", _RegenTextValue));
2134 _RegenText->updateTextContext();
2136 _RegenText->setXReal(_XReal+1);
2137 _RegenText->setYReal(_YReal+2);
2138 _RegenText->setRenderLayer(_RenderLayer+2);
2139 _RegenText->draw();
2143 if (_NotifyAnimEndTime > T1)
2145 if (!_LastSheetId)
2147 _NotifyAnimEndTime = 0;
2149 else
2151 float animProgress = 1.f - float(_NotifyAnimEndTime - T1) / float(NOTIFY_ANIM_MS_DURATION);
2152 sint32 texId = rVR.getSystemTextureId(CViewRenderer::GlowStarTexture);
2153 if (texId != -1)
2155 sint32 texWidth, texHeight;
2156 rVR.getTextureSizeFromId(texId, texWidth, texHeight);
2157 const float freq0 = 1.f;
2158 const float phase0 = 0.f;
2159 const float freq1 = -1.f;
2160 const float phase1 = 0.f;
2161 float scale = sqrtf(1.f - animProgress);
2162 drawRotatedQuad(rVR, float(NLMISC::Pi) * animProgress * freq0 + phase0, scale, _RenderLayer + 3, (uint32)texId, texWidth, texHeight);
2163 drawRotatedQuad(rVR, float(NLMISC::Pi) * animProgress * freq1 + phase1, scale, _RenderLayer + 3, (uint32)texId, texWidth, texHeight);
2170 // ----------------------------------------------------------------------------
2171 void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 texId, sint32 texWidth, sint32 texHeight)
2173 NLMISC::CQuadUV quv;
2174 float cosA = cosf(angle);
2175 float sinA = sinf(angle);
2177 quv.V0.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA + sinA),
2178 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA - cosA), 0.5f);
2180 quv.V1.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA + sinA),
2181 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA - cosA), 0.5f);
2183 quv.V2.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (cosA - sinA),
2184 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (sinA + cosA), 0.5f);
2186 quv.V3.set(_XReal + 0.5f * _WReal + 0.5f * scale * texWidth * (- cosA - sinA),
2187 _YReal + 0.5f * _HReal + 0.5f * scale * texHeight * (- sinA + cosA), 0.5f);
2189 quv.Uv0.set(0.f, 0.f);
2190 quv.Uv1.set(1.f, 0.f);
2191 quv.Uv2.set(1.f, 1.f);
2192 quv.Uv3.set(0.f, 1.f);
2194 vr.drawQuad(renderLayer, quv, texId, CRGBA::White, true);
2198 // ----------------------------------------------------------------------------
2199 inline void CDBCtrlSheet::uvToScreen(float x, float y, CVector &screenPos, uint texSize) const
2201 screenPos.set(_XReal + texSize * x, _YReal + texSize * (1.f - y), 0.5f);
2205 // ----------------------------------------------------------------------------
2206 void CDBCtrlSheet::buildPieCorner(float angle, CUV &uv, CVector &pos, uint texSize) const
2208 float radAngle = angle * 2.f * float(NLMISC::Pi);
2209 // angle origin is at 12'o'clock
2210 float x = cosf(0.5f * float(NLMISC::Pi) - radAngle);
2211 float y = sinf(0.5f * float(NLMISC::Pi) - radAngle);
2212 // project on sides
2213 if (fabsf(y) > fabsf(x))
2215 if (y > 0.f)
2217 // top
2218 x /= y;
2219 y = 1.f;
2221 else
2223 // bottom
2224 x /= -y;
2225 y = -1.f;
2228 else
2230 if (x > 0.f)
2232 y /= x;
2233 x = 1.f;
2235 else
2237 y /= -x;
2238 x = -1.f;
2241 // remap to unit quad
2242 // (well we could have worked with tan() too, I find it simpler this way ....)
2243 uv.set(0.5f * x + 0.5f, 0.5f - 0.5f * y);
2244 uvToScreen(uv.U, uv.V, pos, texSize);
2247 // ----------------------------------------------------------------------------
2248 uint CDBCtrlSheet::buildPie(CQuadUV *triPtr, float startAngle, float endAngle, uint texSize)
2250 static volatile bool exit1 = false;
2251 nlassert(startAngle <= endAngle);
2252 const sint32 factor = 65536;
2253 const float invFactor = 1.f / factor;
2254 sint32 iCurr = (uint32) (startAngle * factor) ;
2255 sint32 iEnd = (uint32) (endAngle * factor);
2256 clamp(iCurr, 0, factor);
2257 clamp(iEnd, 0, factor);
2258 uint triCount = 0;
2259 CVector quadCenter;
2260 uvToScreen(0.5f, 0.5f, quadCenter, texSize);
2262 while (iCurr != iEnd)
2264 sint32 iNext = iCurr + (factor / 4);
2265 iNext -= ((iNext - factor / 8) % (factor / 4)); // snap to nearest corner
2266 iNext = std::min(iNext, iEnd);
2267 // well, not really a quad, but we don't have yet simple triangles rendering in the ui
2268 triPtr->Uv0.set(0.5f, 0.5f);
2269 triPtr->V0 = quadCenter;
2270 buildPieCorner(iCurr * invFactor, triPtr->Uv3, triPtr->V3, texSize);
2271 buildPieCorner(iNext * invFactor, triPtr->Uv2, triPtr->V2, texSize);
2272 // turn a quad into a tri ... :/
2273 triPtr->Uv1 = triPtr->Uv0;
2274 triPtr->V1 = triPtr->V0;
2276 iCurr = iNext;
2278 ++ triPtr;
2279 ++ triCount;
2281 return triCount;
2284 // ----------------------------------------------------------------------------
2285 // Modulate only if iconColor is not White.
2286 static inline CRGBA fastMulRGB(CRGBA sheetColor, CRGBA iconColor)
2288 // NB: the test here is more to avoid loss of precision when icon value is 255,255,255
2289 if(iconColor==CRGBA::White)
2291 return sheetColor;
2293 else
2295 CRGBA ret= sheetColor; // copy alpha from sheetColor
2296 ret.modulateFromColorRGBOnly(sheetColor, iconColor);
2297 return ret;
2301 // ----------------------------------------------------------------------------
2302 void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelectionBorder /*= true*/)
2304 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2305 CViewRenderer &rVR = *CViewRenderer::getInstance();
2306 // The sheet is the slot-2
2307 sint32 wSheet= _WReal-2;
2308 sint32 hSheet= _HReal-2;
2310 // the sheet color is modulated by GlobalAlpha, but not by global RGB
2311 CRGBA curSheetColor= _SheetColor;
2312 curSheetColor.A= ( (CWidgetManager::getInstance()->getGlobalColorForContent().A+1) * _SheetColor.A )>>8;
2313 // The "disp with no sheet" case is a bit different
2314 CRGBA curNoSheetColor;
2315 if(_InterfaceColor)
2316 curNoSheetColor= CWidgetManager::getInstance()->getGlobalColorForContent();
2317 else
2318 curNoSheetColor= CRGBA(255,255,255, CWidgetManager::getInstance()->getGlobalColorForContent().A);
2320 // The gray color
2321 CRGBA grayColor= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionCtrlSheetGrayColor).getValColor();
2322 CRGBA redifyColor= CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionCtrlSheetRedifyColor).getValColor();
2324 // The color of the number.
2325 CRGBA numberColor;
2326 if(!_Useable)
2328 // do not modulate color for redifyed color
2329 numberColor= redifyColor;
2330 numberColor.A= (uint8)(((uint32)redifyColor.A * (CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
2332 else if(_Grayed)
2333 numberColor.modulateFromColor(grayColor, CWidgetManager::getInstance()->getGlobalColorForContent());
2334 else
2335 numberColor= CWidgetManager::getInstance()->getGlobalColorForContent();
2337 // Different draws according to Sheet Type.
2338 switch (_ActualType)
2340 case CCtrlSheetInfo::SheetType_Pact:
2341 setupPact();
2342 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2343 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2344 if (_DispQuality != -1)
2346 // For pact sheets, the quality gives the level of the sheet
2347 drawNumber(x+1, y+1, wSheet, hSheet, numberColor, _DispQuality+1);
2349 break;
2350 case CCtrlSheetInfo::SheetType_Skill:
2351 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::SkillTexture), curSheetColor);
2352 break;
2353 case CCtrlSheetInfo::SheetType_Item:
2354 setupItem();
2356 if(!_Useable)
2357 curSheetColor.modulateFromColor(redifyColor, curSheetColor);
2358 else if (_Grayed || _ItemWeared || _ItemBeastGrayed)
2359 curSheetColor.modulateFromColor(grayColor, curSheetColor);
2361 // if worned display an icon over the item's icon (a red cross for exemple)
2362 if (_Worned.getBool())
2364 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemWornedTexture), curSheetColor);
2367 // Display
2368 if ((_DispSheetBmpId == -1) || (draging && !_DuplicateOnDrag))
2370 if(_DispNoSheetBmpId!=-1)
2372 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2375 else
2377 // Background and icon
2378 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, fastMulRGB(curSheetColor, _IconBackColor));
2379 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, fastMulRGB(curSheetColor, _IconColor));
2381 // if an armour, draw colored part
2382 if (_PackedArmourColor != 0)
2384 CRGBA armourCol;
2385 armourCol.setPacked(_PackedArmourColor);
2386 armourCol.modulateFromColor(curSheetColor, armourCol);
2387 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, armourCol);
2388 // decal layer because must drawn after Items/Brick in DXTC
2389 // NB: use OverColor, not Over2Color here. Because of hack in updateArmourColor()
2390 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor));
2392 else
2394 // decal layer because must drawn after Items/Brick in DXTC
2395 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor));
2396 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
2399 if (_ShowIconBuffs && !_BuffIcons.empty())
2401 // there is max 4 icons
2402 sint32 hArea = (hSheet / 4);
2403 sint32 xIcon = x;
2404 sint32 yIcon = y;
2405 for (uint i = 0; i < _BuffIcons.size(); ++i)
2407 sint32 wIcon = _BuffIcons[i].IconW;
2408 sint32 hIcon = _BuffIcons[i].IconH;
2409 if (hIcon > hArea)
2411 wIcon = wIcon * ((float)hArea / hIcon);
2412 hIcon = hArea;
2414 rVR.drawRotFlipBitmap (_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _BuffIcons[i].TextureId, fastMulRGB(curSheetColor, _BuffIcons[i].Color));
2415 xIcon += wIcon;
2416 // move up the row for 3rd/4th icon
2417 if (i % 3 == 1) {
2418 xIcon = x;
2419 yIcon += hIcon;
2424 // Is the item enchanted ?
2425 sint32 enchant = _Enchant.getSInt32();
2426 if (enchant > 0)
2428 // Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
2429 enchant--;
2430 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
2431 drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
2434 if (_ShowIconBuffs && !_EnchantIcons.empty())
2436 // should only only 2 icons at most
2437 // draw them in single line, top-right
2438 sint32 hArea = (hSheet / 3);
2439 sint32 xIcon = x + wSheet - 1;
2440 sint32 yIcon = y + hSheet - 1/* - hArea*/;
2441 // 0 is expected to be background
2442 for (uint i = 1; i < _EnchantIcons.size(); ++i)
2444 sint32 wIcon = _EnchantIcons[i].IconW;
2445 sint32 hIcon = _EnchantIcons[i].IconH;
2446 if (hIcon > hArea)
2448 wIcon = wIcon * ((float)hArea / hIcon);
2449 hIcon = hArea;
2451 // need to move x before draw because of right aligned
2452 if (i == 1)
2454 xIcon -= wIcon;
2456 yIcon -= hIcon;
2457 rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
2458 rVR.drawRotFlipBitmap(_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
2462 // Draw Quality. -1 for lookandfeel. Draw it with global color
2463 if (_DispQuality != -1)
2465 drawNumber(x-1,y+1,wSheet, hSheet, numberColor, _DispQuality);
2467 // Draw Quantity
2468 if (_UseQuantity && _DispQuantity>-1)
2470 sint32 crossId= rVR.getSystemTextureId(CViewRenderer::QuantityCrossTexture);
2471 sint32 crossW= rVR.getSystemTextureW(CViewRenderer::QuantityCrossTexture);
2472 // +1 for lookandfeel
2473 // draw the "x" bitmap. decal layer because must drawn after Items/Brick in DXTC
2474 rVR.draw11RotFlipBitmap (_RenderLayer+2, x+1, y+1, 0, false, crossId, curSheetColor);
2475 // draw the number next to it
2477 sint32 quantity = _DispQuantity;
2478 if (getLockValuePtr())
2480 quantity -= getLockValuePtr()->getValue32();
2482 drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false);
2485 // if a raw material for example, must add special icon text.
2486 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2488 // Add the lock overlay if needed
2489 if (getLockedByOwner())
2491 rVR.draw11RotFlipBitmap (_RenderLayer+1, x - 2, y + 8, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemLockedByOwnerTexture), curSheetColor);
2494 break;
2495 // Action
2496 case CCtrlSheetInfo::SheetType_Macro:
2497 setupMacro();
2498 if ( ((_DispBackBmpId == -1) && (_DispOverBmpId == -1) && (_DispOver2BmpId == -1)) ||
2499 (draging && isShortCut()) )
2501 if(_DispNoSheetBmpId != -1)
2502 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2504 else
2506 if (_DispBackBmpId != -1)
2507 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2508 if (_DispOverBmpId != -1)
2509 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, curSheetColor);
2510 if (_DispOver2BmpId != -1)
2511 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOver2BmpId, curSheetColor);
2513 // if the pointer is over the button
2514 if (_Over)
2515 // Draw -1,-1 because the slot over is 26x26
2516 rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2518 // Display Macro Text
2520 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2522 break;
2523 case CCtrlSheetInfo::SheetType_GuildFlag:
2524 setupGuildFlag();
2525 if (_UseGuildIcon)
2527 sint32 guildFlagBmpId = -1;
2528 CFactionSheet* guildIconSheet = NULL;
2529 if (_GuildIcon!=NLMISC::CSheetId::Unknown)
2530 guildIconSheet = dynamic_cast<CFactionSheet*>(SheetMngr.get(_GuildIcon));
2531 if (guildIconSheet!=NULL && !guildIconSheet->Icon.empty())
2532 guildFlagBmpId = rVR.getTextureIdFromName(guildIconSheet->Icon);
2533 // else
2534 // guildFlagBmpId = rVR.getTextureIdFromName("asc_unknown.tga");
2535 if (guildFlagBmpId != -1)
2536 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, guildFlagBmpId, curSheetColor);
2538 else if (_MacroID == 0)
2540 if(_DispNoSheetBmpId != -1)
2541 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2543 else
2545 CRGBA col;
2546 col = _SheetColor;
2547 col.modulateFromui (col, curSheetColor.A);
2548 col.A = curSheetColor.A;
2550 rVR.drawCustom (x, y, 32, 32, CUV(0,0), CUV(0.5f,1), CUV(0,0), CUV(1,1), col, _GuildMat);
2552 col= _IconColor;
2553 col.modulateFromui (col, curSheetColor.A);
2554 col.A = curSheetColor.A;
2556 rVR.drawCustom (x, y, 32, 32, CUV(0.5f,0), CUV(1,1), CUV(0,0), CUV(1,1), col, _GuildMat);
2558 // if the pointer is over the button
2559 if (_Over)
2560 // Draw -1,-1 because the slot over is 26x26
2561 rVR.draw11RotFlipBitmap (_RenderLayer+2, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2563 break;
2564 case CCtrlSheetInfo::SheetType_Mission:
2565 setupMission();
2566 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2567 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2568 break;
2569 // same drawing for sbrick and sphrase
2570 case CCtrlSheetInfo::SheetType_SBrick:
2571 case CCtrlSheetInfo::SheetType_SPhraseId:
2572 case CCtrlSheetInfo::SheetType_SPhrase:
2574 switch(_ActualType)
2576 case SheetType_SBrick : setupSBrick(); break;
2577 case SheetType_SPhraseId : setupSPhraseId(); break;
2578 case SheetType_SPhrase : setupSPhrase(); break;
2579 default: nlassert(true); break;
2583 bool showOutOfRangeSymbol = false;
2584 bool forceGrayed = false;
2586 // for phrases, display special icon if a target is selected and if it is too far
2587 if (_ActualType == CCtrlSheetInfo::SheetType_SPhraseId)
2589 sint32 phraseId = getSPhraseId();
2590 if (phraseId)
2592 CSPhraseManager *pPM= CSPhraseManager::getInstance();
2593 const CSPhraseCom &phrase= pPM->getPhrase(phraseId);
2594 // get the phrase Data version, to check if it had changed.
2595 uint32 totalActionMalus = pPM->getTotalActionMalus(phrase);
2596 uint8 targetSlot = UserEntity->targetSlot();
2597 if (targetSlot < CLFECOMMON::INVALID_SLOT)
2599 CEntityCL *target = EntitiesMngr.entity(targetSlot);
2600 if (target && UserEntity)
2602 double dist2 = (target->pos() - UserEntity->pos()).sqrnorm();
2603 CSBrickManager *pBM= CSBrickManager::getInstance();
2604 CSBrickSheet *rootBrick= NULL;
2605 if(phrase.Bricks.size())
2606 rootBrick= pBM->getBrick(phrase.Bricks[0]);
2608 if(rootBrick && rootBrick->isMagic())
2610 // offensive magic can be used against an ennemy only
2611 if(rootBrick->ActionNature == ACTNATURE::OFFENSIVE_MAGIC)
2613 forceGrayed = !target->isEnemy();
2615 else
2618 bool isPrimalMagic = false;
2619 uint i;
2620 for(i=0;i<phrase.Bricks.size();i++)
2622 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
2623 if(brick && brick->BrickFamily == BRICK_FAMILIES::BMSTEA)
2625 isPrimalMagic = true;
2626 break;
2630 if (!isPrimalMagic)
2632 forceGrayed = !(target->isPlayer() && target->isFriend());
2634 else
2636 forceGrayed = false;
2641 if (!forceGrayed)
2643 sint phraseRange;
2644 sint rangeMalus;
2645 pPM->getPhraseMagicRange(phrase, totalActionMalus, phraseRange, rangeMalus);
2646 double rangeDist = (float) (phraseRange + rangeMalus);
2647 if (phraseRange != 0) // if range is '0' then it is a 'self' action
2649 rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
2650 if (dist2 > rangeDist * rangeDist)
2652 showOutOfRangeSymbol = true;
2657 else if(rootBrick && rootBrick->isCombat())
2659 forceGrayed = target->isNeutral();
2661 else if(rootBrick && rootBrick->isSpecialPower())
2663 bool isTaunt = false;
2665 uint maxRange= 255;
2666 uint i;
2667 for(i=0;i<phrase.Bricks.size();i++)
2669 CSBrickSheet *brick= pBM->getBrick(phrase.Bricks[i]);
2670 if (brick)
2672 maxRange= min(maxRange, (uint)brick->MaxRange);
2673 if(brick->BrickFamily == BRICK_FAMILIES::BSFMA)
2676 forceGrayed = target->isNeutral();
2677 isTaunt = true;
2682 if (isTaunt && !forceGrayed)
2684 double rangeDist = (float) maxRange;
2685 rangeDist += 0.5 + target->getSheetScale() * target->getSheetColRadius(); // player radius
2686 if (dist2 > rangeDist * rangeDist)
2688 showOutOfRangeSymbol = true;
2694 // in every cases, test against current gauges to see if the action is possible
2695 if (UserEntity)
2697 sint cost;
2698 sint costMalus;
2699 CBarManager &bm = *CBarManager::getInstance();
2701 pPM->getPhraseHpCost(phrase, totalActionMalus, cost, costMalus);
2702 if (cost > bm.getUserScore(SCORES::hit_points)) forceGrayed = true;
2704 pPM->getPhraseSapCost(phrase, totalActionMalus, cost, costMalus);
2705 if (cost > bm.getUserScore(SCORES::sap)) forceGrayed = true;
2707 pPM->getPhraseStaCost(phrase, totalActionMalus, cost, costMalus);
2708 if (cost > bm.getUserScore(SCORES::stamina)) forceGrayed = true;
2710 pPM->getPhraseFocusCost(phrase, totalActionMalus, cost, costMalus);
2711 if (cost > bm.getUserScore(SCORES::focus)) forceGrayed = true;
2717 if(!_Useable)
2718 curSheetColor.modulateFromColor(redifyColor, curSheetColor);
2719 else if(_Grayed || forceGrayed)
2720 curSheetColor.modulateFromColor(grayColor, curSheetColor);
2722 // display even if draging, fut for memory: act like shortcut
2723 if (_DispSheetBmpId == -1 || (draging && isShortCut()))
2725 if(_DispNoSheetBmpId!=-1)
2727 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispNoSheetBmpId, curNoSheetColor);
2730 else
2732 // center the brick (because may be in an item slot when sheetType is auto)
2733 sint32 px = x + ((_W - 2) / 2) - (BrickSheetWidth / 2);
2734 sint32 py = y + ((_H - 2) / 2) - (BrickSheetHeight / 2);
2736 // The brick must drawn in 24x24 even if bitmap is an item-like (MP knowledge bricks for example)
2737 rVR.drawRotFlipBitmap (_RenderLayer, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispBackBmpId, fastMulRGB(curSheetColor, _IconBackColor));
2738 rVR.drawRotFlipBitmap (_RenderLayer, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispSheetBmpId, fastMulRGB(curSheetColor, _IconColor));
2739 // decal layer because must drawn after Items/Brick in DXTC
2740 rVR.drawRotFlipBitmap (_RenderLayer+1, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor));
2741 rVR.drawRotFlipBitmap (_RenderLayer+1, px, py, BrickSheetWidth, BrickSheetHeight, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
2742 // Draw Quality. -1 for lookandfeel.
2743 if( _ActualType == CCtrlSheetInfo::SheetType_SBrick )
2745 if (_UseQuality && _MustDisplayLevel) drawNumber(px-1,py+1,BrickSheetWidth, BrickSheetHeight, curSheetColor, _DispLevel);
2747 else
2749 // Display SPhrase Icon Name
2750 displayCharBitmaps(_RenderLayer+1, x, y, curSheetColor);
2752 // if the pointer is over the button
2753 if (_Over)
2754 // Draw -1,-1 because the slot over is 26x26
2755 rVR.draw11RotFlipBitmap (_RenderLayer+1, x-1, y-1, 0, false, _TextureIdOver, curSheetColor );
2758 if (showOutOfRangeSymbol)
2760 rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::OutOfRangeTexture), CRGBA::White);
2763 break;
2764 case CCtrlSheetInfo::SheetType_OutpostBuilding:
2765 setupOutpostBuilding();
2766 if (_DispBackBmpId != -1)
2767 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispBackBmpId, curSheetColor);
2768 if (_DispSheetBmpId != -1)
2769 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispSheetBmpId, curSheetColor);
2770 if (_DispOverBmpId != -1)
2771 rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, curSheetColor);
2772 displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
2773 break;
2774 default:
2775 break;
2778 if (showSelectionBorder)
2780 if (!isDragged() || (isDragged() && _DuplicateOnDrag))
2782 // draw selection border if this sheet is selected
2783 if (_SheetSelectionGroup != -1) // is this sheet selectable ?
2784 { // yes, check if it is selected
2785 const CCtrlSheetSelection &css = CWidgetManager::getInstance()->getParser()->getCtrlSheetSelection();
2786 const CSheetSelectionGroup *ssg = css.getGroup(_SheetSelectionGroup);
2787 if (ssg)
2789 // test is the selection group is active and if this item is selected
2790 if (ssg->isActive() && _CurrSelection == this)
2792 // compute middle of the slot
2793 sint32 middleX = _XReal + (_WReal >> 1);
2794 sint32 middleY = _YReal + (_HReal >> 1);
2795 sint32 tw = ssg->getTextureWidth();
2796 sint32 th = ssg->getTextureHeight();
2797 // we are selected -> draw the selection border
2798 CRGBA color = ssg->getColor();
2799 if (ssg->isGlobalColorEnabled())
2801 color.modulateFromColor(color, CWidgetManager::getInstance()->getGlobalColorForContent());
2803 // decal layer because must drawn after Items/Brick in DXTC
2804 rVR.draw11RotFlipBitmap (_RenderLayer+1, middleX - (tw >> 1), middleY - (th >> 1), 0, false, ssg->getTextureIndex(), color);
2812 // ----------------------------------------------------------------------------
2813 sint32 CDBCtrlSheet::drawNumber(sint32 x, sint32 y, sint32 wSheet, sint32 /* hSheet */, CRGBA color, sint32 value, bool rightAlign)
2815 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2816 CViewRenderer &rVR = *CViewRenderer::getInstance();
2817 sint32 wDigit= rVR.getFigurTextureW();
2818 sint32 hDigit= rVR.getFigurTextureH();
2820 sint32 totalWidth = 0;
2822 if (value > -1)
2824 // compute start pos
2825 sint32 units = value;
2826 sint32 pos;
2827 if(rightAlign)
2828 pos= wSheet-wDigit;
2829 else
2831 // compute number of digits to display
2832 pos= 0;
2833 uint numDigits= 0;
2836 units = units / 10;
2837 numDigits++;
2839 while (units != 0);
2840 // so pos is:
2841 pos= numDigits*wDigit - wDigit;
2843 // display digits
2844 units = value;
2847 sint32 unitsID = rVR.getFigurTextureId (units % 10);
2848 // decal layer because must drawn after Items/Brick in DXTC
2849 rVR.drawRotFlipBitmap (_RenderLayer+2, x+pos, y, wDigit, hDigit, 0, false, unitsID, color);
2850 units = units / 10;
2851 pos-= wDigit;
2852 totalWidth += wDigit;
2854 while (units != 0);
2855 return totalWidth;
2857 return -1;
2860 // ----------------------------------------------------------------------------
2861 bool CDBCtrlSheet::handleEvent (const NLGUI::CEventDescriptor &event)
2863 if (CCtrlBase::handleEvent(event)) return true;
2864 CInterfaceManager *pIM = CInterfaceManager::getInstance();
2865 if (event.getType() == NLGUI::CEventDescriptor::mouse)
2867 const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
2869 // Handle drag'n'drop
2870 if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
2872 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown && !isDragged())
2874 _DragX = eventDesc.getX();
2875 _DragY = eventDesc.getY();
2878 bool validClic = false;
2879 if (_DispSheetBmpId!=-1)
2881 // Cannot drag if grayed (LOCKED or LATENT)!. Still can drag a shortcut
2882 if (asItemSheet() && asItemSheet()->Stackable > 1 && _UseQuantity)
2884 validClic = isDraggable() && !isDragged() && (getQuantity() > 0);
2885 validClic = validClic && (!getItemWeared());
2887 else
2889 validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isShortCut());
2892 if (_Type == SheetType_Macro)
2894 validClic = isDraggable();
2897 // posssibly check AH to see if really can draging
2898 if (validClic && _AHOnCanDrag != NULL)
2900 _TempCanDrag= true;
2901 CAHManager::getInstance()->runActionHandler (_AHOnCanDrag, this, _AHCanDragParams);
2902 validClic= _TempCanDrag;
2905 if (validClic)
2907 if ((abs(_DragX-eventDesc.getX()) > 5) || (abs(_DragY-eventDesc.getY()) > 5))
2909 _DeltaDragX= _DragX-(_XReal+1);
2910 _DeltaDragY= _DragY-(_YReal+1);
2911 if (_DeltaDragX > _WReal) _DeltaDragX = _WReal;
2912 if (_DeltaDragY > _HReal) _DeltaDragY = _HReal;
2913 setDragged( true );
2914 setDraggedSheet( this );
2916 if (_AHOnDrag != NULL)
2918 CAHManager::getInstance()->runActionHandler (_AHOnDrag, this, _AHDragParams);
2923 if (isDragged())
2925 // If mouse left up, must end the Drag
2926 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
2928 bool handled = false;
2929 // get the ctrl under the drop
2930 const vector<CCtrlBase*> &rCUP = CWidgetManager::getInstance()->getCtrlsUnderPointer();
2931 CDBCtrlSheet *pCSdest = NULL;
2932 for (uint32 i = 0; i < rCUP.size(); ++i)
2934 CCtrlBase *pCB = rCUP[i];
2935 if (pCB != this)
2937 CDBCtrlSheet *pCS = dynamic_cast<CDBCtrlSheet*>(pCB);
2938 pCSdest = pCS;
2939 if (pCSdest != NULL)
2940 break;
2944 // if ctrl exist
2945 if (pCSdest != NULL)
2947 // dest have a drop action and have a drop request?
2948 if(pCSdest->_AHOnDrop != NULL && pCSdest->_AHOnCanDrop != NULL)
2950 // test if can drop me on dest
2951 pCSdest->_CanDrop= false;
2952 string params = string("src=") + _Id;
2953 if (!pCSdest->_AHCanDropParams.empty())
2955 if (CAHManager::getInstance()->getAHName(pCSdest->_AHOnCanDrop) == "lua")
2957 params = pCSdest->_AHCanDropParams;
2958 strFindReplace(params, "%src", _Id);
2960 else
2962 string sTmp = pCSdest->_AHCanDropParams;
2963 params = sTmp + "|" + params;
2966 CAHManager::getInstance()->runActionHandler (pCSdest->_AHOnCanDrop, pCSdest, params);
2968 // Drop only if canDrop.
2969 if(pCSdest->_CanDrop)
2971 // build params
2972 string params = string("src=") + _Id;
2973 if (!pCSdest->_AHDropParams.empty())
2975 if (CAHManager::getInstance()->getAHName(pCSdest->_AHOnDrop) == "lua")
2977 params = pCSdest->_AHDropParams;
2978 strFindReplace(params, "%src", _Id);
2980 else
2982 string sTmp = pCSdest->_AHDropParams;
2983 params = sTmp + "|" + params;// must copy 'drop' params at start because it could be the name of a procedure
2986 // call action
2987 CAHManager::getInstance()->runActionHandler (pCSdest->_AHOnDrop, pCSdest, params);
2988 handled = true;
2992 else // If slot not found try to drop on a list
2994 // get the list under the drop
2995 const vector<CInterfaceGroup*> &rGUP = CWidgetManager::getInstance()->getGroupsUnderPointer();
2996 CDBGroupListSheet *pList = NULL;
2997 CDBGroupListSheetText *pTextList = NULL;
2998 for (uint32 i = 0; i < rGUP.size(); ++i)
3000 pList = dynamic_cast<CDBGroupListSheet*>(rGUP[i]);
3001 if (pList != NULL)
3002 if (pList->getCanDrop())
3003 break;
3005 pTextList = dynamic_cast<CDBGroupListSheetText*>(rGUP[i]);
3006 if (pTextList != NULL)
3007 if (pTextList->getCanDrop())
3008 break;
3011 if ((pList != NULL) || (pTextList != NULL))
3013 if (pList != NULL)
3014 if (pList->getCtrlSheetInfo()._AHOnDrop != NULL && pList->getCtrlSheetInfo()._AHOnCanDrop != NULL)
3016 pList->setCanDrop(false);
3017 string params = string("src=") + _Id;
3018 if (!pList->getCtrlSheetInfo()._AHCanDropParams.empty())
3020 if (CAHManager::getInstance()->getAHName(pList->getCtrlSheetInfo()._AHOnCanDrop) == "lua")
3022 params = pList->getCtrlSheetInfo()._AHCanDropParams;
3023 strFindReplace(params, "%src", _Id);
3025 else
3027 string sTmp = pList->getCtrlSheetInfo()._AHCanDropParams;
3028 params = sTmp + "|" + params;
3031 CAHManager::getInstance()->runActionHandler (pList->getCtrlSheetInfo()._AHOnCanDrop, pList, params);
3033 // Drop only if canDrop.
3034 if(pList->getCanDrop())
3036 // build params
3037 string params = string("src=") + _Id;
3038 if (!pList->getCtrlSheetInfo()._AHDropParams.empty())
3040 if (CAHManager::getInstance()->getAHName(pList->getCtrlSheetInfo()._AHOnDrop) == "lua")
3042 params = pList->getCtrlSheetInfo()._AHDropParams;
3043 strFindReplace(params, "%src", _Id);
3045 else
3047 string sTmp = pList->getCtrlSheetInfo()._AHDropParams;
3048 params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure
3051 // call action
3052 CAHManager::getInstance()->runActionHandler (pList->getCtrlSheetInfo()._AHOnDrop, pList, params);
3053 handled = true;
3057 if (pTextList != NULL)
3058 if (pTextList->getCtrlSheetInfo()._AHOnDrop != NULL && pTextList->getCtrlSheetInfo()._AHOnCanDrop != NULL)
3060 pTextList->setCanDrop(false);
3061 string params = string("src=") + _Id;
3062 if (!pTextList->getCtrlSheetInfo()._AHCanDropParams.empty())
3064 string sTmp = pTextList->getCtrlSheetInfo()._AHCanDropParams;
3065 params = sTmp + "|" + params;
3067 CAHManager::getInstance()->runActionHandler (pTextList->getCtrlSheetInfo()._AHOnCanDrop, pTextList, params);
3069 // Drop only if canDrop.
3070 if(pTextList->getCanDrop())
3072 // build params
3073 string params = string("src=") + _Id;
3074 if (!pTextList->getCtrlSheetInfo()._AHDropParams.empty())
3076 string sTmp = pTextList->getCtrlSheetInfo()._AHDropParams;
3077 params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure
3079 // call action
3080 CAHManager::getInstance()->runActionHandler (pTextList->getCtrlSheetInfo()._AHOnDrop, pTextList, params);
3081 handled = true;
3088 if (!handled && _AHOnCannotDrop != NULL )
3090 CAHManager::getInstance()->runActionHandler (_AHOnCannotDrop, this, _AHCannotDropParams);
3091 handled = true;
3094 // In all case, quit
3095 setDragged( false );
3096 setDraggedSheet( NULL );
3097 // In call case, end of drag => consider handled to not call another action
3098 return true;
3103 // If we are dragging, no more event on us
3104 if(isDragged())
3105 return false; // true;
3107 // Mouse events that must be done over the control
3108 if (!((eventDesc.getX() >= _XReal) &&
3109 (eventDesc.getX() < (_XReal + _WReal))&&
3110 (eventDesc.getY() > _YReal) &&
3111 (eventDesc.getY() <= (_YReal+ _HReal))))
3112 return false;
3114 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup)
3116 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3117 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
3118 return false;
3120 // RunAction
3121 if(_AHOnLeftClick != NULL)
3122 CAHManager::getInstance()->runActionHandler (_AHOnLeftClick, this, _AHLeftClickParams);
3123 // Run Menu (if item is not being dragged)
3124 if (!_ListMenuLeft.empty() && dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) == NULL)
3126 if (getSheetId() != 0)
3128 _CurrMenuSheet = this;
3129 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuLeft);
3132 // Always return true on LeftClick.
3133 return true;
3136 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown)
3138 return true;
3141 if (eventDesc.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup)
3143 bool handled= false;
3144 CInterfaceManager *pIM = CInterfaceManager::getInstance();
3145 if (CWidgetManager::getInstance()->getCapturePointerRight() != this)
3146 return false;
3148 // RunAction
3149 if(_AHOnRightClick != NULL)
3151 handled= true;
3152 CAHManager::getInstance()->runActionHandler (_AHOnRightClick, this, _AHRightClickParams);
3154 // Run Menu (if item is not being dragged)
3155 if (!_ListMenuRight.empty() || !_ListMenuRightEmptySlot.empty())
3157 handled= true;
3158 // There must be no dragged sheet
3159 if( dynamic_cast< CDBCtrlSheet* >( CCtrlDraggable::getDraggedSheet() ) == NULL)
3161 // if a macro, don't test if Sheet==0
3162 if ( isMacro() || getSheetId() != 0)
3164 if(!_ListMenuRight.empty())
3166 _CurrMenuSheet = this;
3167 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRight);
3170 // if sheetId==0, then may open the other menu
3171 else
3173 if(!_ListMenuRightEmptySlot.empty())
3175 _CurrMenuSheet = this;
3176 CWidgetManager::getInstance()->enableModalWindow (this, _ListMenuRightEmptySlot);
3181 // If not handled here, ret to parent
3182 return handled;
3186 return false;
3190 // ----------------------------------------------------------------------------
3191 CCDBNodeBranch *CDBCtrlSheet::getRootBranch() const
3193 if (_SheetId.getNodePtr())
3195 return _SheetId.getNodePtr()->getParent();
3197 return NULL;
3201 // ***************************************************************************
3202 static void swapDBProps(CCDBNodeLeaf *a, CCDBNodeLeaf *b)
3204 if(!a || !b)
3205 return;
3206 sint32 val= a->getValue32();
3207 a->setValue32(b->getValue32());
3208 b->setValue32(val);
3211 // ***************************************************************************
3212 void CDBCtrlSheet::swapSheet(CDBCtrlSheet *other)
3214 sint32 sheetId= other->_SheetId.getSInt32();
3215 other->_SheetId.setSInt32(_SheetId.getSInt32());
3216 _SheetId.setSInt32(sheetId);
3217 // For Items try to swap all other infos
3218 if(_ActualType==SheetType_Item)
3220 // quantity
3221 _Quantity.swap32(other->_Quantity);
3222 _Quality.swap32(other->_Quality);
3223 _NameId.swap32(other->_NameId);
3224 _Enchant.swap32(other->_Enchant);
3226 // swap the other props only if the DB exist in the 2 version. else no-op
3227 swapDBProps(_UserColor, other->_UserColor);
3228 swapDBProps(getItemLockedPtr(), other->getItemLockedPtr());
3229 swapDBProps(getItemWeightPtr(), other->getItemWeightPtr());
3230 swapDBProps(getItemInfoVersionPtr(), other->getItemInfoVersionPtr());
3231 swapDBProps(getItemRMClassTypePtr(), other->getItemRMClassTypePtr());
3232 swapDBProps(getItemRMFaberStatTypePtr(), other->getItemRMFaberStatTypePtr());
3233 swapDBProps(getItemPrerequisitValidPtr(), other->getItemPrerequisitValidPtr());
3234 swapDBProps(getItemSerialPtr(), other->getItemSerialPtr());
3235 swapDBProps(getItemCreateTimePtr(), other->getItemCreateTimePtr());
3239 // ***************************************************************************
3240 void CDBCtrlSheet::setCurrSelection(CDBCtrlSheet *selected)
3242 _CurrSelection = selected;
3243 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:SHEET")->setValue64(selected ? selected->getSheetId() : 0);
3244 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:QUALITY")->setValue64(selected ? selected->getQuality() : 0);
3245 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SHEET_ID:SLOT_TYPE")->setValue64(selected ? selected->getBehaviour() : 0);
3246 // set the selection group in the db
3247 NLGUI::CDBManager::getInstance()->getDbProp("UI:SELECTED_ITEM_SELECTION_GROUP")->setValue64(selected ? selected->getSelectionGroup() : -1);
3250 // ***************************************************************************
3251 const std::string &CDBCtrlSheet::getSelectionGroupAsString() const
3253 CInterfaceManager *im = CInterfaceManager::getInstance();
3254 const CCtrlSheetSelection &css = CWidgetManager::getInstance()->getParser()->getCtrlSheetSelection();
3255 const CSheetSelectionGroup *csg = css.getGroup(_SheetSelectionGroup);
3256 static const string emptyStr;
3257 return csg ? csg->getName() : emptyStr;
3260 // ***************************************************************************
3261 sint32 CDBCtrlSheet::getNonLockedQuantity() const
3263 sint32 nonLockedQt = getQuantity();
3264 CCDBNodeLeaf *lockedPtr = getItemLockedPtr();
3265 if (lockedPtr != NULL)
3266 nonLockedQt -= lockedPtr->getValue32();
3267 if (nonLockedQt < 0)
3268 nonLockedQt = 0;
3269 return nonLockedQt;
3272 // ***************************************************************************
3273 const CItemSheet *CDBCtrlSheet::asItemSheet() const
3275 updateActualType();
3276 if( _ActualType!=SheetType_Item )
3277 return NULL;
3279 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3280 if (sheet && sheet->type() == CEntitySheet::ITEM)
3282 return (CItemSheet *) sheet;
3284 return NULL;
3287 // ***************************************************************************
3288 const CPactSheet *CDBCtrlSheet::asPactSheet() const
3290 updateActualType();
3291 if( _ActualType!=SheetType_Pact )
3292 return NULL;
3294 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3295 if (sheet && sheet->type() == CEntitySheet::PACT)
3297 return (CPactSheet *) sheet;
3299 return NULL;
3302 // ***************************************************************************
3303 const CSBrickSheet *CDBCtrlSheet::asSBrickSheet() const
3305 updateActualType();
3306 if( _ActualType!=SheetType_SBrick )
3307 return NULL;
3309 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3310 if (sheet && sheet->type() == CEntitySheet::SBRICK)
3312 return (CSBrickSheet *) sheet;
3314 return NULL;
3317 // ***************************************************************************
3318 const CSPhraseSheet *CDBCtrlSheet::asSPhraseSheet() const
3320 updateActualType();
3321 if( _ActualType!=SheetType_SPhrase )
3322 return NULL;
3324 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3325 if (sheet && sheet->type() == CEntitySheet::SPHRASE)
3327 return (CSPhraseSheet *) sheet;
3329 return NULL;
3332 // ***************************************************************************
3333 const COutpostBuildingSheet *CDBCtrlSheet::asOutpostBuildingSheet() const
3335 updateActualType();
3336 if (_ActualType != SheetType_OutpostBuilding)
3337 return NULL;
3339 CEntitySheet *sheet = SheetMngr.get(CSheetId(getSheetId()));
3340 if (sheet && sheet->type() == CEntitySheet::OUTPOST_BUILDING)
3342 return (COutpostBuildingSheet *) sheet;
3344 return NULL;
3347 // ***************************************************************************
3348 void CDBCtrlSheet::setupItemInfoWaiter()
3350 const CItemSheet *item = asItemSheet();
3351 if(!item)
3353 clearIconBuffs();
3354 return;
3357 if (!useItemInfoForFamily(item->Family))
3359 clearIconBuffs();
3360 return;
3363 if (getItemSerial() == 0 || getItemCreateTime() == 0)
3365 clearIconBuffs();
3366 return;
3369 string luaMethodName = ((item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip");
3370 CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
3371 uint itemSlotId = getInventory().getItemSlotId(ctrlSheet);
3373 // Prepare the waiter for tooltips
3374 _ItemInfoWaiter.ItemSheet= ctrlSheet->getSheetId();
3375 _ItemInfoWaiter.LuaMethodName = luaMethodName;
3376 _ItemInfoWaiter.ItemSlotId= itemSlotId;
3377 _ItemInfoWaiter.CtrlSheet = ctrlSheet;
3379 // send out request only if cache is not set
3380 const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
3381 if (itemInfo)
3383 infoReceived();
3385 else
3387 // Using isInventoryPresent/Available() will fail for packers when out of range
3388 // Getting server item however will work correctly for packer/room/guild
3389 const CItemImage *itemImage = getInventory().getServerItem(itemSlotId);
3390 if (itemImage)
3392 _ItemInfoWaiter.sendRequest();
3394 else
3396 // schedule for next draw() - if inventory should not be available (ie guild),
3397 // but user opens it anyway, then this will loop back here on every draw()
3398 _ItemInfoChanged = true;
3403 // ***************************************************************************
3404 void CDBCtrlSheet::getContextHelp(std::string &help) const
3406 if (getType() == CCtrlSheetInfo::SheetType_Skill)
3408 // just show the name of the skill
3409 // the sheet id is interpreted as a skill enum
3410 help= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName( (SKILLS::ESkills)_SheetId.getSInt32() );
3412 else if(getType() == CCtrlSheetInfo::SheetType_Macro)
3414 help = _ContextHelp;
3415 const CMacroCmd *macro = CMacroCmdManager::getInstance()->getMacroFromMacroID(getMacroId());
3416 if (!macro)
3417 return;
3419 string macroName = macro->Name;
3420 if (macroName.empty())
3421 macroName = CI18N::get("uiNotAssigned");
3423 string assignedTo = macro->Combo.toString();
3424 if (assignedTo.empty())
3425 assignedTo = CI18N::get("uiNotAssigned");
3427 string dispText;
3428 string dispCommands;
3429 const CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
3431 uint nb = 0;
3432 for (uint i = 0; i < macro->Commands.size(); ++i)
3434 string commandName;
3435 for (uint j = 0; j < pMCM->ActionManagers.size(); ++j)
3437 CAction::CName c(macro->Commands[i].Name.c_str(), macro->Commands[i].Params.c_str());
3438 if (pMCM->ActionManagers[j]->getBaseAction(c) != NULL)
3440 commandName = pMCM->ActionManagers[j]->getBaseAction(c)->getActionLocalizedText(c);
3441 // display a few commands
3442 if (nb < 5)
3443 dispCommands += "\n" + commandName;
3444 ++nb;
3445 break;
3449 // formats
3450 dispText = "%n (@{6F6F}%k@{FFFF})\n%c";
3451 if (nb > 5) // more?
3452 dispCommands += toString(" ... @{6F6F}%i@{FFFF}+", nb-5);
3454 strFindReplace(dispText, "%n", macroName);
3455 strFindReplace(dispText, "%k", assignedTo);
3456 strFindReplace(dispText, "%c", dispCommands);
3457 help = dispText;
3459 else if(getType() == CCtrlSheetInfo::SheetType_Item)
3461 const CItemSheet *item= asItemSheet();
3462 if(item)
3464 if (useItemInfoForFamily(item->Family))
3466 // call lua function to update tooltip window
3467 _ItemInfoWaiter.sendRequest();
3468 help = _ItemInfoWaiter.infoValidated();
3469 // its expected to get at least item name back
3470 if (help.empty())
3471 help = getItemActualName();
3473 else if (!_ContextHelp.empty())
3475 help = _ContextHelp;
3477 else
3479 help = getItemActualName();;
3482 else
3483 help= _ContextHelp;
3485 else if(getType() == CCtrlSheetInfo::SheetType_Pact)
3487 const CPactSheet *item= asPactSheet();
3488 if(item)
3490 sint32 quality = getQuality();
3491 if (quality >= (sint32) 0 && quality < (sint32) item->PactLose.size())
3493 help= item->PactLose[quality].Name;
3495 else
3497 help= _ContextHelp;
3500 else
3502 help= _ContextHelp;
3505 else if(getType() == CCtrlSheetInfo::SheetType_SBrick)
3507 CSBrickManager *pBM= CSBrickManager::getInstance();
3508 CSBrickSheet *brick= pBM->getBrick(CSheetId(getSheetId()));
3509 if(brick)
3510 help= STRING_MANAGER::CStringManagerClient::getSBrickLocalizedName(brick->Id);
3511 else
3512 help= _ContextHelp;
3514 else if(getType() == CCtrlSheetInfo::SheetType_SPhraseId)
3516 sint32 phraseId= getSheetId();
3517 if (phraseId == 0)
3519 help = std::string();
3521 else
3523 // delegate setup of context he help ( & window ) to lua
3524 CInterfaceManager *im = CInterfaceManager::getInstance();
3525 CLuaState *ls= CLuaManager::getInstance().getLuaState();
3527 CLuaStackRestorer lsr(ls, 0);
3528 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3529 _PhraseAdapter = new CSPhraseComAdpater;
3530 _PhraseAdapter->Phrase = pPM->getPhrase(phraseId);
3531 CLuaIHM::pushReflectableOnStack(*ls, _PhraseAdapter);
3532 ls->pushGlobalTable();
3533 CLuaObject game(*ls);
3534 game = game["game"];
3535 game.callMethodByNameNoThrow("updatePhraseTooltip", 1, 1);
3536 // retrieve result from stack
3537 if (!ls->empty())
3539 #ifdef RYZOM_LUA_UCSTRING
3540 ucstring tmpHelp; // Compatibility
3541 CLuaIHM::pop(*ls, tmpHelp);
3542 help = tmpHelp.toUtf8();
3543 #else
3544 help = ls->toString();
3545 ls->pop();
3546 #endif
3548 else
3550 nlwarning("Ucstring result expected when calling 'game:updatePhraseTooltip', possible script error");
3555 CSPhraseManager *pPM= CSPhraseManager::getInstance();
3556 // The sheetId point to a phrase in the manager, get it
3557 sint32 phraseId= getSheetId();
3558 if(phraseId)
3559 help= pPM->getPhrase(phraseId).Name;
3560 else
3561 help= _ContextHelp;
3563 sint32 phraseSheetID = pPM->getSheetFromPhrase(pPM->getPhrase(phraseId));
3564 if (phraseSheetID != 0)
3566 // is it a built-in phrase?
3567 string desc = STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedDescription(NLMISC::CSheetId(phraseSheetID));
3568 if (!desc.empty())
3570 help += "\n\n@{CCCF}" + desc;
3575 else if(getType() == CCtrlSheetInfo::SheetType_SPhrase)
3577 CSPhraseSheet *phrase= dynamic_cast<CSPhraseSheet*>(SheetMngr.get(CSheetId(getSheetId())));
3578 if(phrase)
3579 help= STRING_MANAGER::CStringManagerClient::getSPhraseLocalizedName(phrase->Id);
3580 else
3581 help= _ContextHelp;
3583 else if(getType() == CCtrlSheetInfo::SheetType_OutpostBuilding)
3585 const COutpostBuildingSheet *outpost = asOutpostBuildingSheet();
3586 if (outpost)
3587 help = CStringManagerClient::getOutpostBuildingLocalizedName(CSheetId(_SheetId.getSInt32()));
3588 else
3589 help = _ContextHelp;
3593 // ***************************************************************************
3594 void CDBCtrlSheet::getContextHelpToolTip(std::string &help) const
3596 // Special case for buff items and spell crystals, only for tooltips
3597 if (getType() == CCtrlSheetInfo::SheetType_Item)
3599 const CItemSheet *item = asItemSheet();
3600 if (item)
3602 if (useItemInfoForFamily(item->Family))
3604 _ItemInfoWaiter.sendRequest();
3605 help = _ItemInfoWaiter.infoValidated();
3606 return;
3611 // Default
3612 getContextHelp(help);
3615 // ***************************************************************************
3616 bool CDBCtrlSheet::canDropItem(CDBCtrlSheet *src) const
3618 if( src->getSheetId()==0 )
3619 return true;
3621 // If the dest or src is Grayed, cannot drop it
3622 if( src->getInventoryIndex() != INVENTORIES::exchange)
3624 if (src->getGrayed() || getGrayed()) return false;
3625 if (src->getItemWeared() || getItemWeared()) return false;
3628 // if no filter defined => OK.
3629 if( _ItemSlot== SLOTTYPE::UNDEFINED )
3630 return true;
3633 // Verify the item slot of the src
3634 CSheetId sheetId(src->getSheetId());
3635 CEntitySheet *pES = SheetMngr.get (sheetId);
3636 if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM))
3638 CItemSheet *pIS = (CItemSheet*)pES;
3640 // build the bitField for test.
3641 uint32 bf;
3642 bf= 1<<_ItemSlot;
3643 // special for right hand
3644 if( _ItemSlot== SLOTTYPE::RIGHT_HAND )
3646 // Can put an object in right hand also if it is TWO_HANDS, or RIGHT_HAND_EXCLUSIVE
3647 bf|= 1<<SLOTTYPE::TWO_HANDS;
3648 bf|= 1<<SLOTTYPE::RIGHT_HAND_EXCLUSIVE;
3651 // Look if one slot solution match.
3652 if( pIS->SlotBF & bf )
3654 // Ok the object is compatible with the dest
3656 // Can put an object in left or right hand is dependent of other hand content
3657 if( _OtherHandItemFilter && (_ItemSlot == SLOTTYPE::LEFT_HAND || _ItemSlot == SLOTTYPE::RIGHT_HAND) )
3659 // special for left hand
3660 if( _ItemSlot == SLOTTYPE::LEFT_HAND )
3662 // If the item comes from right hand cant drop
3663 if (src->_ItemSlot == SLOTTYPE::RIGHT_HAND)
3664 return false;
3665 // get the item in the right hand
3666 CSheetId sheetId(_OtherHandItemFilter->getSheetId());
3667 CEntitySheet *pRightHandES = SheetMngr.get (sheetId);
3668 // if item present: must check if the right has a TWO_HANDS or RIGHT_HAND_EXCLUSIVE
3669 if ( pRightHandES != NULL && pRightHandES->type() == CEntitySheet::ITEM )
3671 CItemSheet *pRightHandIS = (CItemSheet*)pRightHandES;
3672 if( pRightHandIS->hasSlot(SLOTTYPE::TWO_HANDS) ||
3673 pRightHandIS->hasSlot(SLOTTYPE::RIGHT_HAND_EXCLUSIVE) )
3674 return false;
3676 // if the current item we wants to drop is a dagger, check if right hand is a sword or a dagger
3677 if (pIS->ItemType == ITEM_TYPE::DAGGER)
3679 if ((pRightHandIS->ItemType != ITEM_TYPE::DAGGER) &&
3680 (pRightHandIS->ItemType != ITEM_TYPE::SWORD))
3681 return false;
3684 else
3686 // If nothing valid in right hand cant drop a dagger
3687 if (pIS->ItemType == ITEM_TYPE::DAGGER)
3688 return false;
3691 // special for right hand
3692 else
3695 // If the right hand do not contains a two hand item
3696 bool bRightHandContainsTwoHandItem = false;
3697 CSheetId sheetId(getSheetId());
3698 CEntitySheet *pOwnES = SheetMngr.get (sheetId);
3699 // if item present: must check if the right has a TWO_HANDS or RIGHT_HAND_EXCLUSIVE
3700 if ( pOwnES != NULL && pOwnES->type() == CEntitySheet::ITEM )
3702 CItemSheet *pOwnIS = (CItemSheet*)pOwnES;
3703 if( pOwnIS->hasSlot( SLOTTYPE::TWO_HANDS ) || pOwnIS->hasSlot( SLOTTYPE::RIGHT_HAND_EXCLUSIVE ) )
3704 bRightHandContainsTwoHandItem = true;
3707 // if the LeftHand is not empty, and If the item we want to drop is a 2Hands item, CANNOT drop
3708 if (!bRightHandContainsTwoHandItem)
3709 if( _OtherHandItemFilter->getSheetId()!=0 )
3710 if( pIS->hasSlot( SLOTTYPE::TWO_HANDS ) || pIS->hasSlot( SLOTTYPE::RIGHT_HAND_EXCLUSIVE ) )
3712 return false;
3718 // Check if the ammo has the same type as the hand containing the weapon
3719 if( _OtherHandItemFilter && (_ItemSlot== SLOTTYPE::AMMO))
3721 CSheetId sheetId(_OtherHandItemFilter->getSheetId());
3722 CEntitySheet *pESWeapon = SheetMngr.get (sheetId);
3723 if ( pESWeapon == NULL || pESWeapon->type() != CEntitySheet::ITEM )
3724 return false;
3725 CItemSheet *pISWeapon = (CItemSheet*)pESWeapon;
3726 if (pISWeapon->Family != ITEMFAMILY::RANGE_WEAPON)
3727 return false;
3728 if(pIS->Family != ITEMFAMILY::AMMO)
3729 return false;
3730 if (pISWeapon->RangeWeapon.Skill != pIS->Ammo.Skill)
3731 return false;
3734 // ok, can drop!
3735 return true;
3737 else
3738 return false;
3742 // Default: OK
3743 return true;
3746 // ***************************************************************************
3747 void CDBCtrlSheet::updateActualType() const
3749 if (_Type == SheetType_Auto)
3751 TSheetType newType;
3752 if (isMission())
3754 newType = SheetType_Mission;
3756 else if (isSkill())
3758 newType = SheetType_Skill;
3760 else
3762 // get type from sheet id
3763 CEntitySheet *es = SheetMngr.get(CSheetId(_SheetId.getSInt32()));
3764 if (!es)
3766 newType = SheetType_Item;
3768 else
3770 switch(es->type())
3772 case CEntitySheet::ITEM: newType = SheetType_Item; break;
3773 case CEntitySheet::PACT: newType = SheetType_Pact; break;
3774 case CEntitySheet::SBRICK: newType = SheetType_SBrick; break;
3775 case CEntitySheet::SPHRASE: newType = SheetType_SPhrase; break;
3776 case CEntitySheet::OUTPOST_BUILDING: newType = SheetType_OutpostBuilding; break;
3777 default:
3778 newType = SheetType_Item;
3779 break;
3784 // if type changed, must reset some ctrl state (important for list sheet trade for instance else
3785 // new SPhrase can get aspect of old SItem (eg: Upper-Left MP Text and Redified color...)
3786 if(newType!=_ActualType)
3788 _ActualType= newType;
3789 const_cast<CDBCtrlSheet*>(this)->_Grayed= false;
3790 const_cast<CDBCtrlSheet*>(this)->_Useable= true;
3791 const_cast<CDBCtrlSheet*>(this)->_OptString.clear();
3792 const_cast<CDBCtrlSheet*>(this)->resetCharBitmaps();
3795 else
3797 _ActualType = _Type;
3801 // ***************************************************************************
3802 void CDBCtrlSheet::setType(CCtrlSheetInfo::TSheetType type)
3804 _ActualType = _Type = type;
3805 _NeedSetup = true;
3808 // ***************************************************************************
3809 void CDBCtrlSheet::resetAllTexIDs()
3811 _DispSheetBmpId = -1;
3812 _DispBackBmpId = -1;
3813 _DispOverBmpId = -1;
3814 _DispOver2BmpId = -1;
3815 _DispQuality = -1;
3816 _DispQuantity= -1;
3817 _Stackable= 1;
3818 _IconW = 0;
3819 _IconH = 0;
3821 _ItemInfoChanged = true;
3822 _EnchantIcons.clear();
3823 _BuffIcons.clear();
3827 // ***************************************************************************
3828 CCtrlSheetInfo::TSheetType CDBCtrlSheet::getType() const
3830 if (_Type == SheetType_GuildFlag) return SheetType_GuildFlag;
3832 if (_Type != SheetType_Macro)
3834 if (_LastSheetId != _SheetId.getSInt32())
3836 updateActualType();
3837 _LastSheetId = _SheetId.getSInt32();
3838 _NeedSetup = true;
3840 return _ActualType;
3842 else
3844 return SheetType_Macro;
3848 // ***************************************************************************
3849 void CDBCtrlSheet::setBehaviour(TRADE_SLOT_TYPE::TTradeSlotType type)
3851 if (_HasTradeSlotType)
3853 _TradeSlotType.setSInt32(type);
3857 // ***************************************************************************
3858 void CDBCtrlSheet::copyAspect(CDBCtrlSheet *dest)
3860 dest->setType(getType());
3861 dest->setSheetId(getSheetId());
3862 if (!isSBrickOrSPhraseId() && !isMission())
3864 if (getUseQuality())
3866 dest->setUseQuality(true);
3867 if (_Quality.getNodePtr() != NULL)
3868 dest->setQuality(getQuality());
3869 dest->setReadQuantityFromSheetFlag(getReadQuantityFromSheetFlag());
3871 else
3873 dest->setUseQuality(false);
3875 if (getUseQuantity())
3877 dest->setUseQuantity(true);
3878 if (_Quantity.getNodePtr() != NULL)
3879 dest->setQuantity(getQuantity());
3881 else
3883 dest->setUseQuantity(false);
3885 // copy color for items
3886 sint col = getItemColor();
3887 if (col != -1) dest->setItemColor(col);
3888 // copy weight
3889 dest->setItemWeight(getItemWeight());
3890 // copy nameId
3891 dest->setItemNameId(getItemNameId());
3892 // copy info version
3893 dest->setItemInfoVersion(getItemInfoVersion());
3894 // copy enchant info
3895 dest->setEnchant(getEnchant());
3896 // copy faber faber quality
3897 dest->setItemRMClassType(getItemRMClassType());
3898 // copy faber faber stat type
3899 dest->setItemRMFaberStatType(getItemRMFaberStatType());
3900 // copy faber faber stat type
3901 dest->setItemRMFaberStatType(getItemRMFaberStatType());
3902 // copy prerequisit valid flag
3903 dest->setItemPrerequisitValid(getItemPrerequisitValid());
3904 // copy item serial
3905 dest->setItemSerial(getItemSerial());
3906 // copy item create time
3907 dest->setItemCreateTime(getItemCreateTime());
3909 // if brick, sphrase or sphraseId
3910 if(isSBrick() || isSPhrase() || isSPhraseId())
3912 // must reset dest Useable/Redifyed and slotType (in case precedent type was Item!)
3913 dest->setGrayed(false);
3914 dest->_Useable= true;
3915 dest->_OptString.clear();
3916 dest->resetCharBitmaps();
3918 // misc
3919 if (dest->_HasTradeSlotType) dest->setBehaviour(getBehaviour());
3920 dest->invalidateCoords();
3921 dest->initSheetSize();
3924 dest->_NeedSetup = true;
3927 // ***************************************************************************
3928 bool CDBCtrlSheet::sameAspect(CDBCtrlSheet *dest) const
3930 if( dest->getType() != getType() )
3931 return false;
3932 if( dest->getSheetId() != getSheetId() )
3933 return false;
3934 if (!isSBrickOrSPhraseId() && !isSPhrase())
3937 if( dest->getUseQuality() != getUseQuality() )
3938 return false;
3939 if( getUseQuality() && _Quality.getNodePtr() != NULL )
3941 if( dest->getQuality() != getQuality() )
3942 return false;
3944 if( dest->getUseQuantity() != getUseQuantity() )
3945 return false;
3946 if( getUseQuantity() && _Quantity.getNodePtr() != NULL )
3948 if( dest->getQuantity() != getQuantity() )
3949 return false;
3951 if( dest->getEnchant() != getEnchant() )
3952 return false;
3953 if( dest->getRMClassType() != getRMClassType() )
3954 return false;
3955 if( dest->getRMFaberStatType() != getRMFaberStatType() )
3956 return false;
3958 return false; // nico v : Items can be different because of their item info. So can't conclude about equality.
3959 // default to false for safety
3961 if (dest->_HasTradeSlotType)
3963 if( dest->getBehaviour() != getBehaviour() )
3964 return false;
3967 return true;
3970 // ***************************************************************************
3971 CDBCtrlSheet::TSheetCategory CDBCtrlSheet::getSheetCategory() const
3973 if (isSkill()) return Skill;
3974 if (getType() == SheetType_Pact) return Pact;
3975 if (getType() == SheetType_GuildFlag) return GuildFlag;
3976 if (getType() == SheetType_Mission) return Mission;
3977 if (isSPhrase()) return Phrase;
3978 return Item;
3981 // ***************************************************************************
3982 bool CDBCtrlSheet::isMission() const
3984 CCDBNodeBranch *root = getRootBranch();
3985 if (!root) return false;
3986 CCDBNodeLeaf *node = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("ICON"), false));
3987 return node != NULL;
3990 // ***************************************************************************
3991 void CDBCtrlSheet::setupInit()
3993 _SetupInit= true;
3995 // Init _OtherHandItemFilter (with the opti string)
3996 if( !_OptString.empty() )
3998 // typically replace "handl" with "handr" or vice versa
3999 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4000 CInterfaceElement *pElt = CWidgetManager::getInstance()->getElementFromId (_Id, _OptString);
4001 CDBCtrlSheet *pOtherHand = dynamic_cast<CDBCtrlSheet*>(pElt);
4002 if( !pOtherHand || pOtherHand ->getType() != CCtrlSheetInfo::SheetType_Item )
4004 nlwarning("%s: other_hand_slot error", _Id.c_str());
4006 _OtherHandItemFilter= pOtherHand;
4010 // ***************************************************************************
4011 IListSheetBase *CDBCtrlSheet::getListSheetParent() const
4013 IListSheetBase *parent = dynamic_cast<IListSheetBase *>(_Parent);
4014 // ListSheetTrade double parent sons (intermeidate _List)
4015 if(!parent && _Parent)
4017 parent = dynamic_cast<IListSheetBase *>(_Parent->getParent());
4019 return parent;
4022 // ***************************************************************************
4023 sint CDBCtrlSheet::getIndexInParent() const
4025 IListSheetBase *parent= getListSheetParent();
4026 if (!parent) return -1;
4027 return parent->getIndexOf(this);
4030 // ***************************************************************************
4031 void CDBCtrlSheet::readFromMacro(const CMacroCmd &mc)
4033 if (_Type != SheetType_Macro) return;
4034 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4036 _DispBackBmpId = (mc.BitmapBack == 0xFF) ? -1 : pMCM->getTexIdBack(mc.BitmapBack);
4038 _DispOverBmpId = (mc.BitmapIcon == 0xFF) ? -1 : pMCM->getTexIdIcon(mc.BitmapIcon);
4040 _DispOver2BmpId = (mc.BitmapOver == 0xFF) ? -1 : pMCM->getTexIdOver(mc.BitmapOver);
4042 _OptString = mc.DispText;
4043 _NeedSetup = true;
4044 _MacroID = mc.ID;
4047 // ***************************************************************************
4048 void CDBCtrlSheet::writeToMacro(CMacroCmd &mc)
4050 uint i = 0;
4051 if (_Type != SheetType_Macro) return;
4052 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4054 // Find back
4055 if (_DispBackBmpId == -1)
4057 mc.BitmapBack = 0xFF;
4059 else
4061 i = 0;
4062 while (i != 255)
4064 if (pMCM->getTexIdBack(i) == _DispBackBmpId) break;
4065 i++;
4067 if (i == 255) nlwarning("cannot find back id for macro");
4068 mc.BitmapBack = i;
4071 // Find Icon
4072 if (_DispOverBmpId == -1)
4074 mc.BitmapIcon = 0xFF;
4076 else
4078 i = 0;
4079 while (i != 255)
4081 if (pMCM->getTexIdIcon(i) == _DispOverBmpId) break;
4082 i++;
4084 if (i == 255) nlwarning("cannot find icon id for macro");
4085 mc.BitmapIcon = i;
4088 // Find over
4089 if (_DispOver2BmpId == -1)
4091 mc.BitmapOver = 0xFF;
4093 else
4095 i = 0;
4096 while (i != 255)
4098 if (pMCM->getTexIdOver(i) == _DispOver2BmpId) break;
4099 i++;
4101 if (i == 255) nlwarning("cannot find over id for macro");
4102 mc.BitmapOver = i;
4105 mc.DispText = _OptString;
4106 mc.ID = _MacroID;
4110 // ***************************************************************************
4111 void CDBCtrlSheet::setMacroBack(uint8 nb)
4113 if (_Type != SheetType_Macro) return;
4114 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4115 _DispBackBmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdBack(nb);
4118 // ***************************************************************************
4119 void CDBCtrlSheet::setMacroIcon(uint8 nb)
4121 if (_Type != SheetType_Macro) return;
4122 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4123 _DispOverBmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdIcon(nb);
4126 // ***************************************************************************
4127 void CDBCtrlSheet::setMacroOver(uint8 nb)
4129 if (_Type != SheetType_Macro) return;
4130 CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
4131 _DispOver2BmpId = (nb == 0xFF) ? -1 : pMCM->getTexIdOver(nb);
4134 // ***************************************************************************
4135 void CDBCtrlSheet::setMacroText(const std::string &mcText)
4137 _OptString = mcText;
4138 _NeedSetup = true;
4141 // ***************************************************************************
4142 bool CDBCtrlSheet::isSheetValid() const
4144 // get the actual type
4145 TSheetType type= getType();
4147 sint32 sid = 0;
4148 bool validSheet = false;
4150 if ((type != SheetType_Macro) && (type != SheetType_Skill))
4152 sid = getSheetId();
4153 validSheet = (sid!=0);
4155 // different test according to type
4156 switch(type)
4158 // brick OK?
4159 // always for macros and skills enums
4160 case SheetType_Macro:
4161 case SheetType_Skill:
4162 validSheet= true;
4163 break;
4164 case SheetType_GuildFlag:
4165 // sid == name, quality == icon if both are != 0 then its a valid guild flag
4166 validSheet= (sid!=0)&&(_Quality.getSInt32() != 0);
4167 break;
4168 // SBrick OK?
4169 case SheetType_SBrick:
4170 validSheet= validSheet && CSBrickManager::getInstance()->getBrick(CSheetId((uint32)sid));
4171 break;
4172 case SheetType_SPhraseId:
4173 // Suppose phrase always valid but if 0.
4174 break;
4175 // Same for Items, Pact, and SPhrase
4176 default:
4177 validSheet= validSheet && SheetMngr.get(CSheetId((uint32)sid));
4178 validSheet= validSheet && (!_ItemWeared);
4179 break;
4182 // TODO_BRICK: SPhrase / SPhraseId????
4184 return validSheet;
4187 // ***************************************************************************
4188 // GUILD_FLAG
4189 // ***************************************************************************
4191 // ***************************************************************************
4192 CRGBA CDBCtrlSheet::getGuildColor1() const
4194 CRGBA col = CRGBA::White;
4195 if (_Type != SheetType_GuildFlag) return col;
4196 uint64 nGuildIcon = _Quality.getSInt64();
4197 return CGuildManager::iconGetColor1(nGuildIcon);
4200 // ***************************************************************************
4201 CRGBA CDBCtrlSheet::getGuildColor2() const
4203 CRGBA col=CRGBA::White;
4204 if (_Type != SheetType_GuildFlag) return col;
4205 uint64 nGuildIcon = _Quality.getSInt64();
4206 return CGuildManager::iconGetColor2(nGuildIcon);
4209 // ***************************************************************************
4210 sint32 CDBCtrlSheet::getGuildBack() const
4212 sint32 back = 0;
4213 if (_Type != SheetType_GuildFlag) return back;
4214 uint64 nGuildIcon = _Quality.getSInt64();
4215 return CGuildManager::iconGetBack(nGuildIcon);
4218 // ***************************************************************************
4219 sint32 CDBCtrlSheet::getGuildSymbol() const
4221 sint32 symb = 0;
4222 if (_Type != SheetType_GuildFlag) return symb;
4223 uint64 nGuildIcon = _Quality.getSInt64();
4224 return CGuildManager::iconGetSymbol(nGuildIcon);
4227 // ***************************************************************************
4228 bool CDBCtrlSheet::getInvertGuildSymbol() const
4230 if (_Type != SheetType_GuildFlag) return false;
4231 uint64 nGuildIcon = _Quality.getSInt64();
4232 return CGuildManager::iconGetInvertSymbol(nGuildIcon);
4235 // ***************************************************************************
4236 void CDBCtrlSheet::setGuildColor1(CRGBA col)
4238 if (_Type != SheetType_GuildFlag) return;
4239 // Clean up bits
4240 uint64 nGuildIcon = _Quality.getSInt64();
4241 CGuildManager::iconSetColor1(nGuildIcon, col);
4242 _Quality.setSInt64(nGuildIcon);
4245 // ***************************************************************************
4246 void CDBCtrlSheet::setGuildColor2(CRGBA col)
4248 if (_Type != SheetType_GuildFlag) return;
4249 // Clean up bits
4250 uint64 nGuildIcon = _Quality.getSInt64();
4251 CGuildManager::iconSetColor2(nGuildIcon, col);
4252 _Quality.setSInt64(nGuildIcon);
4255 // ***************************************************************************
4256 void CDBCtrlSheet::setGuildBack(sint32 n)
4258 if (_Type != SheetType_GuildFlag) return;
4259 // Clean up bits
4260 uint64 nGuildIcon = _Quality.getSInt64();
4261 CGuildManager::iconSetBack(nGuildIcon, (uint8)n);
4262 _Quality.setSInt64(nGuildIcon);
4265 // ***************************************************************************
4266 void CDBCtrlSheet::setGuildSymbol(sint32 n)
4268 if (_Type != SheetType_GuildFlag) return;
4269 // Clean up bits
4270 uint64 nGuildIcon = _Quality.getSInt64();
4271 CGuildManager::iconSetSymbol(nGuildIcon, (uint8)n);
4272 _Quality.setSInt64(nGuildIcon);
4275 // ***************************************************************************
4276 void CDBCtrlSheet::setInvertGuildSymbol(bool b)
4278 if (_Type != SheetType_GuildFlag) return;
4279 // Clean up bits
4280 uint64 nGuildIcon = _Quality.getSInt64();
4281 CGuildManager::iconSetInvertSymbol(nGuildIcon, b);
4282 _Quality.setSInt64(nGuildIcon);
4285 // ***************************************************************************
4286 void CDBCtrlSheet::setSlot(const std::string &textureName)
4288 CInterfaceManager *pIM = CInterfaceManager::getInstance();
4289 CViewRenderer &rVR = *CViewRenderer::getInstance();
4290 _DispSlotBmpId = rVR.getTextureIdFromName (textureName);
4291 rVR.getTextureSizeFromId (_DispSlotBmpId, _W, _H);
4292 _DrawSlot = true;
4295 // ***************************************************************************
4296 // SBrick
4297 // ***************************************************************************
4299 // ***************************************************************************
4300 bool CDBCtrlSheet::isSPhraseIdMemory() const
4302 if(!isSPhraseId())
4303 return false;
4305 // test if mem match
4306 if( 0 == _DbBranchName.compare(0, PHRASE_DB_MEMORY.size(), PHRASE_DB_MEMORY) )
4307 return true;
4308 return false;
4311 // ***************************************************************************
4312 bool CDBCtrlSheet::isMacroMemory() const
4314 if(!isMacro())
4315 return false;
4317 // test if mem match
4318 if( 0 == _DbBranchName.compare(0, PHRASE_DB_MEMORY.size(), PHRASE_DB_MEMORY) )
4319 return true;
4320 return false;
4323 // ***************************************************************************
4324 uint8 CDBCtrlSheet::getItemInfoVersion() const
4326 CCDBNodeLeaf *node = getItemInfoVersionPtr();
4327 return node ? (uint8) node->getValue8() : 0;
4330 // ***************************************************************************
4331 CCDBNodeLeaf *CDBCtrlSheet::getItemInfoVersionPtr() const
4333 CCDBNodeBranch *root = getRootBranch();
4334 if (!root) return NULL;
4335 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("INFO_VERSION"), false));
4338 // ***************************************************************************
4339 void CDBCtrlSheet::setItemInfoVersion(uint8 infoVersion)
4341 CCDBNodeLeaf *node = getItemInfoVersionPtr();
4342 if (node) node->setValue8((sint8) infoVersion);
4345 // ***************************************************************************
4346 CCDBNodeLeaf *CDBCtrlSheet::getItemWeightPtr() const
4348 CCDBNodeBranch *root = getRootBranch();
4349 if (!root) return NULL;
4350 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("WEIGHT"), false));
4353 // ***************************************************************************
4354 uint16 CDBCtrlSheet::getItemWeight() const
4356 CCDBNodeLeaf *node = getItemWeightPtr();
4357 return node ? (uint16) node->getValue16() : 0;
4360 // ***************************************************************************
4361 void CDBCtrlSheet::setItemWeight(uint16 weight)
4363 CCDBNodeLeaf *node = getItemWeightPtr();
4364 if (node) node->setValue16((sint16) weight);
4367 // ***************************************************************************
4368 CCDBNodeLeaf *CDBCtrlSheet::getItemLockedPtr() const
4370 CCDBNodeBranch *root = getRootBranch();
4371 if (!root) return NULL;
4372 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("LOCKED"), false));
4375 // ***************************************************************************
4376 uint16 CDBCtrlSheet::getItemLocked() const
4378 CCDBNodeLeaf *node = getItemLockedPtr();
4379 if (!node) return -1;
4380 return (sint) node->getValue32();
4383 // ***************************************************************************
4384 void CDBCtrlSheet::setItemLocked(uint16 lock)
4386 CCDBNodeLeaf *node = getItemLockedPtr();
4387 if (!node) return;
4388 node->setValue32(lock);
4391 // ***************************************************************************
4392 sint32 CDBCtrlSheet::getItemPrice() const
4394 CCDBNodeLeaf *node = getItemPricePtr();
4395 if (!node) return 0;
4396 return node->getValue32();
4399 // ***************************************************************************
4400 CCDBNodeLeaf *CDBCtrlSheet::getItemPricePtr() const
4402 CCDBNodeBranch *root = getRootBranch();
4403 if (!root) return NULL;
4404 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("PRICE"), false));
4407 // ***************************************************************************
4408 void CDBCtrlSheet::setItemPrice(sint32 price)
4410 CCDBNodeLeaf *node = getItemPricePtr();
4411 if (!node) return;
4412 node->setValue32(price);
4415 // ***************************************************************************
4416 sint32 CDBCtrlSheet::getItemResaleFlag() const
4418 CCDBNodeLeaf *node = getItemResaleFlagPtr();
4419 if (!node) return 0;
4420 return node->getValue32();
4423 // ***************************************************************************
4424 CCDBNodeLeaf *CDBCtrlSheet::getItemResaleFlagPtr() const
4426 CCDBNodeBranch *root = getRootBranch();
4427 if (!root) return NULL;
4428 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("RESALE_FLAG"), false));
4431 // ***************************************************************************
4432 void CDBCtrlSheet::setItemResaleFlag(sint32 rf)
4434 CCDBNodeLeaf *node = getItemResaleFlagPtr();
4435 if (!node) return;
4436 node->setValue32(rf);
4439 // ***************************************************************************
4440 sint32 CDBCtrlSheet::getItemCreateTime() const
4442 CCDBNodeLeaf *node = getItemCreateTimePtr();
4443 if (!node) return 0;
4444 return node->getValue32();
4447 // ***************************************************************************
4448 CCDBNodeLeaf *CDBCtrlSheet::getItemCreateTimePtr() const
4450 CCDBNodeBranch *root = getRootBranch();
4451 if (!root) return NULL;
4452 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("CREATE_TIME"), false));
4455 // ***************************************************************************
4456 void CDBCtrlSheet::setItemCreateTime(sint32 ct)
4458 CCDBNodeLeaf *node = getItemCreateTimePtr();
4459 if (!node) return;
4460 node->setValue32(ct);
4463 // ***************************************************************************
4464 sint32 CDBCtrlSheet::getItemSerial() const
4466 CCDBNodeLeaf *node = getItemSerialPtr();
4467 if (!node) return 0;
4468 return node->getValue32();
4471 // ***************************************************************************
4472 CCDBNodeLeaf *CDBCtrlSheet::getItemSerialPtr() const
4474 CCDBNodeBranch *root = getRootBranch();
4475 if (!root) return NULL;
4476 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("SERIAL"), false));
4479 // ***************************************************************************
4480 void CDBCtrlSheet::setItemSerial(sint32 rf)
4482 CCDBNodeLeaf *node = getItemSerialPtr();
4483 if (!node) return;
4484 node->setValue32(rf);
4487 // ***************************************************************************
4488 bool CDBCtrlSheet::getLockedByOwner() const
4490 return (getItemResaleFlag() == BOTCHATTYPE::ResaleKOLockedByOwner);
4493 // ***************************************************************************
4494 bool CDBCtrlSheet::canOwnerLock() const
4496 return (NULL != getItemResaleFlagPtr());
4499 // ***************************************************************************
4500 sint32 CDBCtrlSheet::getItemSellerType() const
4502 CCDBNodeLeaf *node = getItemSellerTypePtr();
4503 if (!node) return 0;
4504 return node->getValue32();
4507 // ***************************************************************************
4508 CCDBNodeLeaf *CDBCtrlSheet::getItemSellerTypePtr() const
4510 CCDBNodeBranch *root = getRootBranch();
4511 if (!root) return NULL;
4512 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("SELLER_TYPE"), false));
4515 // ***************************************************************************
4516 void CDBCtrlSheet::setItemSellerType(sint32 rf)
4518 CCDBNodeLeaf *node = getItemSellerTypePtr();
4519 if (!node) return;
4520 node->setValue32(rf);
4523 // ***************************************************************************
4524 RM_CLASS_TYPE::TRMClassType CDBCtrlSheet::getItemRMClassType() const
4526 CCDBNodeLeaf *node = getItemRMClassTypePtr();
4527 return (RM_CLASS_TYPE::TRMClassType) (node ? node->getValue32() : 0);
4530 // ***************************************************************************
4531 void CDBCtrlSheet::setItemRMClassType(sint32 fq)
4533 CCDBNodeLeaf *node = getItemRMClassTypePtr();
4534 if (!node) return;
4535 node->setValue32(fq);
4538 // ***************************************************************************
4539 RM_FABER_STAT_TYPE::TRMStatType CDBCtrlSheet::getItemRMFaberStatType() const
4541 CCDBNodeLeaf *node = getItemRMFaberStatTypePtr();
4542 return (RM_FABER_STAT_TYPE::TRMStatType) (node ? node->getValue32() : 0);
4545 // ***************************************************************************
4546 void CDBCtrlSheet::setItemRMFaberStatType(sint32 fss)
4548 CCDBNodeLeaf *node = getItemRMFaberStatTypePtr();
4549 if (!node) return;
4550 node->setValue32(fss);
4553 // ***************************************************************************
4554 bool CDBCtrlSheet::getItemPrerequisitValid() const
4556 CCDBNodeLeaf *node = getItemPrerequisitValidPtr();
4557 return (bool) (node ? node->getValueBool() : true);
4560 // ***************************************************************************
4561 CCDBNodeLeaf *CDBCtrlSheet::getItemPrerequisitValidPtr() const
4563 CCDBNodeBranch *root = getRootBranch();
4564 if (!root) return NULL;
4565 return dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("PREREQUISIT_VALID"), false));
4568 // ***************************************************************************
4569 void CDBCtrlSheet::setItemPrerequisitValid(bool prv)
4571 CCDBNodeLeaf *node = getItemPrerequisitValidPtr();
4572 if (!node) return;
4573 node->setValueBool(prv);
4576 // ***************************************************************************
4577 void CDBCtrlSheet::initArmourColors()
4579 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4581 for(uint col = 0; col < RM_COLOR::NumColors; ++col)
4583 _ArmourColor[col] = CRGBA::White;
4584 std::string defineName= "armour_color_" + toString(col);
4585 std::string colVal= CWidgetManager::getInstance()->getParser()->getDefine(defineName);
4586 if(!colVal.empty())
4587 _ArmourColor[col] = convertColor(colVal.c_str());
4592 // ***************************************************************************
4593 string CDBCtrlSheet::getItemActualName() const
4595 const CItemSheet *pIS= asItemSheet();
4596 if(!pIS)
4597 return string();
4598 else
4600 string ret;
4601 // If NameId not 0, get from StringManager
4602 uint32 nameId= getItemNameId();
4603 if(nameId)
4605 STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
4606 pSMC->getDynString(nameId, ret);
4608 // else get standard localized version
4609 else
4611 ret = STRING_MANAGER::CStringManagerClient::getItemLocalizedName(pIS->Id);
4614 if (pIS->Family == ITEMFAMILY::SCROLL_R2)
4616 const R2::TMissionItem *mi = R2::getEditor().getPlotItemInfos(getSheetId());
4617 if (mi) return mi->Name.toUtf8();
4619 // if item is not a mp, append faber_quality & faber_stat_type
4620 // Don't append quality and stat type for Named Items!!!
4621 if (!nameId &&
4622 (pIS->Family == ITEMFAMILY::ARMOR ||
4623 pIS->Family == ITEMFAMILY::MELEE_WEAPON ||
4624 pIS->Family == ITEMFAMILY::RANGE_WEAPON ||
4625 pIS->Family == ITEMFAMILY::AMMO ||
4626 pIS->Family == ITEMFAMILY::SHIELD ||
4627 pIS->Family == ITEMFAMILY::JEWELRY)
4630 // get description string for item format
4631 std::string formatID = getItemRMFaberStatType() != RM_FABER_STAT_TYPE::Unknown ? "uihelpItemFaberPrefixAndSuffix" : "uihelpItemFaberPrefix";
4632 string format;
4633 if (!CI18N::hasTranslation(formatID))
4635 format = "%p %n %s"; // not found, uses default string
4637 else
4639 format = CI18N::get(formatID);
4641 // suffix
4642 strFindReplace(format, "%p", RM_CLASS_TYPE::toLocalString(getItemRMClassType()));
4643 // name
4644 strFindReplace(format, "%n", ret);
4645 // prefix
4646 strFindReplace(format, "%s", CI18N::get(toString("mpstatItemQualifier%d", (int) getItemRMFaberStatType()).c_str()));
4649 ret = format;
4651 return ret;
4655 // ***************************************************************************
4656 void CDBCtrlSheet::updateArmourColor(sint8 col)
4658 // bkup index cache (bkup -1 too)
4659 _ArmourColorIndex= col;
4661 if(_ArmourColorIndex>=0 && _ArmourColorIndex<=7)
4663 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4664 CViewRenderer &rVR= *CViewRenderer::getInstance();
4666 // if the BMP have not been correctly setuped
4667 if(!_ArmourColorBmpOk)
4669 _ArmourColorBmpOk= true;
4671 if (_DispOverBmpId != -1)
4673 _DispOver2BmpId = _DispOverBmpId;
4675 std::string iconName = rVR.getTextureNameFromId(_DispSheetBmpId);
4676 std::string maskName = CFile::getFilenameWithoutExtension(iconName) + "_mask." + CFile::getExtension(iconName);
4677 _DispOverBmpId = rVR.getTextureIdFromName (maskName);
4680 // new true color
4681 _PackedArmourColor = _ArmourColor[col].getPacked();
4685 // ***************************************************************************
4686 bool CDBCtrlSheet::checkItemRequirement()
4688 if(getType()!=SheetType_Item)
4689 return true;
4691 // If quality not used, well, cannot check item requirement.
4692 if(!_UseQuality)
4693 return true;
4695 // NB: we cannot test directly _Useable, because callers typically call this method BEFORE updateCoords()
4697 // If this is not the same sheet/quality, need to resetup charac requirement
4699 sint32 sheet = _SheetId.getSInt32();
4700 if (_LastSheetId != sheet || _NeedSetup || _Quality.getSInt32()!=_DispQuality)
4702 // NB: don't update cache, leave this feature to updateCoords()
4703 // Special Item requirement
4704 updateItemCharacRequirement(sheet);
4707 // at each frame, must test for Redifyed (player carac does not met item requirement)
4708 CInterfaceManager *pIM= CInterfaceManager::getInstance();
4710 bool retVal = pIM->isItemCaracRequirementMet(_ItemCaracReqType, _ItemCaracReqValue);
4712 if (retVal && _ItemSheet)
4714 if (_ItemSheet->RequiredCharac != CHARACTERISTICS::Unknown && _ItemSheet->RequiredCharacLevel>0)
4715 retVal = pIM->isItemCaracRequirementMet(_ItemSheet->RequiredCharac, _ItemSheet->RequiredCharacLevel);
4717 if (retVal && _ItemSheet->RequiredSkillLevel > 0 && _ItemSheet->RequiredSkill != SKILLS::unknown)
4718 _Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
4720 return retVal;
4722 return _Useable = _PrerequisitValid.getBool();
4726 bool NoOpForCCtrlSheetInfo_Serial = false; // Prevent an assert in CDBCtrlSheet::serial (set externally) for a very specific case.
4727 // The only case where an empty implementation is ok is for r2 in edition mode
4728 // when building in scene interface for entities (the CDBCtrlSheet are hidden then ...!) /
4730 // ***************************************************************************
4731 void CDBCtrlSheet::serial(NLMISC::IStream &f)
4733 CCtrlBase::serial(f);
4734 if (NoOpForCCtrlSheetInfo_Serial) return; // no-op for now
4735 nlassert(0); // !! IMPLEMENT ME !!
4738 // ***************************************************************************
4739 std::string CDBCtrlSheet::getContextHelpWindowName() const
4741 if (getType() == CCtrlSheetInfo::SheetType_SPhraseId)
4743 return "action_context_help";
4745 if (getType() == CCtrlSheetInfo::SheetType_Item)
4747 const CItemSheet *item= asItemSheet();
4748 if(item && useItemInfoForFamily(item->Family))
4750 if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL)
4752 return "crystallized_spell_context_help";
4754 else
4756 return "buff_item_context_help";
4760 return CCtrlBase::getContextHelpWindowName();
4764 // ***************************************************************************
4765 void CDBCtrlSheet::setRegenTickRange(const CTickRange &tickRange)
4767 _RegenTickRange = tickRange;
4770 // ***************************************************************************
4771 void CDBCtrlSheet::startNotifyAnim()
4773 _NotifyAnimEndTime = T1 + NOTIFY_ANIM_MS_DURATION;