1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2020 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012 Matt RAYKOWSKI (sfb) <matt.raykowski@gmail.com>
6 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
27 #include "nel/gui/action_handler.h"
28 #include "interface_manager.h"
29 #include "bot_chat_manager.h"
30 #include "../sheet_manager.h"
31 #include "skill_manager.h"
32 #include "dbctrl_sheet.h"
33 #include "nel/gui/interface_expr.h"
34 #include "nel/gui/group_container.h"
35 #include "nel/gui/group_editbox.h"
36 #include "group_quick_help.h"
37 #include "nel/gui/view_text_id.h"
38 #include "../user_entity.h"
39 #include "../entities.h"
40 #include "nel/gui/dbgroup_combo_box.h"
41 #include "nel/gui/dbview_bar.h"
42 #include "../debug_client.h"
43 #include "interface_3d_scene.h"
44 #include "character_3d.h"
45 #include "item_special_effect.h"
46 #include "item_consumable_effect.h"
47 #include "bonus_malus.h"
49 #include "game_share/slot_types.h"
50 #include "game_share/item_family.h"
51 #include "game_share/skills.h"
52 #include "game_share/armor_types.h"
53 #include "game_share/weapon_types.h"
54 #include "game_share/damage_types.h"
55 #include "game_share/ecosystem.h"
56 #include "game_share/mp_category.h"
57 #include "game_share/item_origin.h"
58 #include "game_share/shield_types.h"
59 #include "game_share/trade_slot_type.h"
60 #include "../string_manager_client.h"
61 #include "game_share/sphrase_com.h"
62 #include "sbrick_manager.h"
63 #include "sphrase_manager.h"
64 #include "action_handler_help.h"
65 #include "nel/misc/i18n.h"
66 #include "nel/misc/algo.h"
67 #include "nel/net/email.h"
68 #include "game_share/mission_desc.h"
69 #include "game_share/inventories.h"
70 #include "game_share/visual_slot_manager.h"
71 #include "game_share/prerequisit_infos.h"
72 #include "game_share/resistance_type.h"
73 #include "../r2/editor.h"
75 #include "../browse_faq.h"
76 #include "people_list.h"
77 #include "people_interraction.h"
79 extern CSheetManager SheetMngr
;
81 extern NLMISC::CLog g_log
;
84 using namespace NLMISC
;
85 using namespace STRING_MANAGER
;
88 ///////////////////////////////////
89 // STATIC FUNCTIONS DECLARATIONS //
90 ///////////////////////////////////
91 static void setupCreatorName(CSheetHelpSetup
&setup
);
92 static void setHelpText(CSheetHelpSetup
&setup
, const string
&text
);
93 static void setHelpTextID(CSheetHelpSetup
&setup
, sint32 id
);
94 static void fillSabrinaPhraseListBrick(const CSPhraseCom
&phrase
, IListSheetBase
*listBrick
);
95 static void setupListBrickHeader(CSheetHelpSetup
&setup
);
96 static void hideListBrickHeader(CSheetHelpSetup
&setup
);
98 static void setupHelpPage(CInterfaceGroup
*window
, const string
&url
);
99 static void setupHelpTitle(CInterfaceGroup
*group
, const string
&title
);
100 static void setHelpCtrlSheet(CSheetHelpSetup
&setup
, uint32 sheetId
);
102 // Setup help for an item in a window (type is known)
103 static void setupItemHelp(CSheetHelpSetup
&setup
);
104 static void setupPactHelp(CSheetHelpSetup
&setup
);
105 static void setupSkillToTradeHelp(CSheetHelpSetup
&setup
);
106 static void setupSabrinaBrickHelp(CSheetHelpSetup
&setup
, bool auraDisabled
= false);
107 void setupSabrinaPhraseHelp(CSheetHelpSetup
&setup
, const class CSPhraseCom
&phrase
, uint32 phraseSheetId
);
108 static void setupMissionHelp(CSheetHelpSetup
&setup
);
110 // ***************************************************************************
111 #define INFO_LIST_ITEM "list_item"
112 #define INFO_LIST_BRICK "list_brick"
113 #define INFO_LIST_BRICK_HEADER "list_brick_header"
114 #define INFO_LIST_BRICK_REQUIREMENT "list_brick_requirement"
115 #define INFO_GROUP_MP_STAT "mp_stats"
116 #define INFO_GROUP_CHAR_3D "char3d"
117 #define INFO_ITEM_PREVIEW "item_preview"
118 #define INFO_ITEM_PREVIEW_SCENE_3D "scene_item_preview"
119 #define ITEM_PREVIEW_WIDTH 200
121 // ***************************************************************************
122 std::deque
<uint
> CInterfaceHelp::_ActiveWindows
;
123 std::vector
<CInterfaceHelp::CInfoWindow
> CInterfaceHelp::_InfoWindows
;
124 bool CInterfaceHelp::_InfoWindowInit
= false;
125 CInterfaceHelp::CFittedWeaponWeightObserver
CInterfaceHelp::_FittedWeaponWeightObserver
;
128 // ***************************************************************************
129 void CInterfaceHelp::CInfoWindow::infoReceived()
132 if(CtrlSheet
&& Window
)
134 CSheetHelpSetup setup
;
135 setup
.setupDefaultIDs();
136 setup
.HelpWindow
= Window
;
137 setup
.SrcSheet
= CtrlSheet
;
138 refreshItemHelp(setup
);
142 // ***************************************************************************
143 void CInterfaceHelp::CInfoWindow::missionInfoReceived(const CPrerequisitInfos
&infos
)
146 if(CtrlSheet
&& Window
)
148 CSheetHelpSetup setup
;
149 setup
.setupDefaultIDs();
150 setup
.HelpWindow
= Window
;
151 setup
.SrcSheet
= CtrlSheet
;
152 refreshMissionHelp(setup
, infos
);
156 // ***************************************************************************
157 void CInterfaceHelp::initWindows()
162 _InfoWindowInit
= true;
164 // Get the Max window allowed.
165 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
168 fromString(CWidgetManager::getInstance()->getParser()->getDefine("MAX_HELP_WINDOW"), maxHelpWindow
);
170 // Allow Max 256. More may be a script error...
171 clamp(maxHelpWindow
, 0, 256);
173 for(sint i
=0;i
<maxHelpWindow
;i
++)
175 CInterfaceGroup
*group
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:sheet_help"+toString(i
)));
176 // if the window exist, insert
180 newInfo
.Window
= group
->getId();
181 newInfo
.KeepButton
= group
->getId() + ":header_opened:keep";
182 _InfoWindows
.push_back(newInfo
);
187 // add observers for the update of phrase help texts (depends of weight of equipped weapons)
188 for (uint i
= 0; i
< MAX_HANDINV_ENTRIES
; ++i
)
190 CCDBNodeLeaf
*pNodeLeaf
= NLGUI::CDBManager::getInstance()->getDbProp(string(LOCAL_INVENTORY
) + ":HAND:" + toString(i
), false);
193 ICDBNode::CTextId textId
;
194 pNodeLeaf
->addObserver(&_FittedWeaponWeightObserver
, textId
);
201 // ***************************************************************************
202 void CInterfaceHelp::release()
206 _InfoWindowInit
= false;
207 _InfoWindows
.clear();
209 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
210 // add observers for the update of phrase help texts (depends of weight of equipped weapons)
211 for (uint i
= 0; i
< MAX_HANDINV_ENTRIES
; ++i
)
213 CCDBNodeLeaf
*pNodeLeaf
= NLGUI::CDBManager::getInstance()->getDbProp(string(LOCAL_INVENTORY
) + ":HAND:" + toString(i
), false);
216 ICDBNode::CTextId textId
;
217 pNodeLeaf
->removeObserver(&_FittedWeaponWeightObserver
, textId
);
222 // ***************************************************************************
223 void CInterfaceHelp::CFittedWeaponWeightObserver::update(ICDBNode
* node
)
225 CInterfaceHelp::updateWindowSPhraseTexts();
228 // ***************************************************************************
229 CInterfaceGroup
*CInterfaceHelp::activateNextWindow(CDBCtrlSheet
*elt
, sint forceKeepWindow
)
231 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
233 // update WindowList if possible
235 sint maxHelpWindow
= (sint
)_InfoWindows
.size();
238 // Update Active window list
240 for(i
=0;i
<_ActiveWindows
.size();)
242 CInterfaceGroup
*group
= _InfoWindows
[_ActiveWindows
[i
]].Window
;
243 // if the window has been closed, remove it from list
244 if(!group
->getActive())
246 _ActiveWindows
.erase(_ActiveWindows
.begin()+i
);
252 bool showSlotAndCreator
= false;
253 // If an active window get the same object, abort, but make it top.
254 for(i
=0;i
<_ActiveWindows
.size();i
++)
256 CInterfaceGroup
*group
= _InfoWindows
[_ActiveWindows
[i
]].Window
;
257 CDBCtrlSheet
*ctrlSrc
= elt
;
258 // get the ctrl sheet in this help window.
259 CDBCtrlSheet
*ctrlDst
= dynamic_cast<CDBCtrlSheet
*>(group
->getCtrl(":ctrl_slot"));
260 if(ctrlDst
&& ctrlSrc
)
263 if( ctrlSrc
->sameAspect(ctrlDst
) )
267 // for items, must also test if they have the same itemSlotId, cause relies also on "ItemInfo system"
268 if(elt
->getType() == CCtrlSheetInfo::SheetType_Item
)
270 showSlotAndCreator
= true;
272 CDBCtrlSheet
*realCtrlDst
= _InfoWindows
[_ActiveWindows
[i
]].CtrlSheet
;
275 else if( getInventory().getItemSlotId(ctrlSrc
) != getInventory().getItemSlotId(realCtrlDst
) )
279 // if success to find same element
282 // then don't neet to open a new window, but make the older top.
283 CWidgetManager::getInstance()->setTopWindow(group
);
290 // If some free window possible, search which to take
291 sint newIndexWindow
= -1;
292 bool mustAddToActiveWindows
= true;
293 // if an active window is not in KeepMode, get it.
294 for(i
=0;i
<_ActiveWindows
.size();i
++)
296 // must also test forceKeep for special Action Help which open Brick Help
297 if(!_InfoWindows
[_ActiveWindows
[i
]].KeepMode
&& forceKeepWindow
!=(sint
)_ActiveWindows
[i
])
299 newIndexWindow
= _ActiveWindows
[i
];
300 mustAddToActiveWindows
= false;
305 // If not found get new closed one.
306 if(newIndexWindow
==-1)
308 if(_ActiveWindows
.size() < (uint
)maxHelpWindow
)
310 // flag each active window
311 static std::vector
<bool> windowActive
;
312 windowActive
.clear();
313 windowActive
.resize(maxHelpWindow
, false);
314 for(i
=0;i
<_ActiveWindows
.size();i
++)
316 windowActive
[_ActiveWindows
[i
]]= true;
319 // Search the first window closed, and that is in KeepMode (if possible)
320 sint newIndexWindowKeep
= -1;
321 for(i
=0;i
<(uint
)maxHelpWindow
;i
++)
325 // Keep the first window not active
326 if(newIndexWindow
==-1)
328 // Keep the first window not active, that is in KeepMode
329 if(_InfoWindows
[i
].KeepMode
&& newIndexWindowKeep
==-1)
330 newIndexWindowKeep
= i
;
334 if( newIndexWindow
==-1 )
336 // success to take a "keep" one?
337 if(newIndexWindowKeep
!=-1)
338 newIndexWindow
= newIndexWindowKeep
;
342 // All the info window are opened (and should not be in KeepMode....), take the last recently opened.
343 newIndexWindow
= _ActiveWindows
.front();
345 _ActiveWindows
.pop_front();
349 // get the next window
350 CInterfaceGroup
*group
= _InfoWindows
[newIndexWindow
].Window
;
353 CInterfaceElement
*ctrl
= group
->getElement(group
->getId()+":content:ctrl_slot");
354 if (ctrl
) ctrl
->setActive(showSlotAndCreator
);
355 ctrl
= group
->getElement(group
->getId()+":content:creator");
356 if (ctrl
) ctrl
->setActive(showSlotAndCreator
);
357 ctrl
= group
->getElement(group
->getId()+":content:creator_header");
358 if (ctrl
) ctrl
->setActive(showSlotAndCreator
);
360 // activate it, set top, copy item watched
361 group
->setActive(true);
362 CWidgetManager::getInstance()->setTopWindow(group
);
363 _InfoWindows
[newIndexWindow
].CtrlSheet
= elt
;
365 if(mustAddToActiveWindows
)
366 _ActiveWindows
.push_back(newIndexWindow
);
368 // If Item or mission, must add a callBack when itemInfo (or missionInfo) OK.
371 if( elt
->getType() == CCtrlSheetInfo::SheetType_Item
)
373 _InfoWindows
[newIndexWindow
].ItemSheet
= elt
->getSheetId();
374 _InfoWindows
[newIndexWindow
].ItemSlotId
= getInventory().getItemSlotId(elt
);
376 // Add the waiter only if really needed (not for raw materials)
377 const CItemSheet
*itemSheet
= elt
->asItemSheet();
378 if(itemSheet
&& itemSheet
->Family
!= ITEMFAMILY::RAW_MATERIAL
)
379 getInventory().addItemInfoWaiter(&_InfoWindows
[newIndexWindow
]);
381 else if ( elt
->getType() == CCtrlSheetInfo::SheetType_Mission
)
383 _InfoWindows
[newIndexWindow
].MissionSlotId
= (uint16
)elt
->getIndexInDB();
384 CBotChatManager::getInstance()->addMissionInfoWaiter(&_InfoWindows
[newIndexWindow
]);
388 // recompute at next pass
389 group
->invalidateCoords();
391 // Hide some components.
392 // Hide the creator name
393 CSheetHelpSetup setup
;
394 setup
.setupDefaultIDs();
395 setup
.SrcSheet
= elt
;
396 setup
.HelpWindow
= group
;
397 //setupCreatorName(setup);
399 // Hide elements by defaults
400 resetSheetHelp(setup
);
406 // ***************************************************************************
407 void CInterfaceHelp::removeWaiterItemInfo(uint i
)
409 if(i
<_InfoWindows
.size())
410 getInventory().removeItemInfoWaiter(&_InfoWindows
[i
]);
413 // ***************************************************************************
414 void CInterfaceHelp::removeWaiterMissionInfo(uint i
)
416 if(i
<_InfoWindows
.size())
417 CBotChatManager::getInstance()->removeMissionInfoWaiter(&_InfoWindows
[i
]);
420 // ***************************************************************************
421 void CInterfaceHelp::changeKeepMode(uint i
)
423 if(i
<_InfoWindows
.size())
425 _InfoWindows
[i
].KeepMode
= !_InfoWindows
[i
].KeepMode
;
426 bool state
= _InfoWindows
[i
].KeepMode
;
427 if(_InfoWindows
[i
].KeepButton
)
428 _InfoWindows
[i
].KeepButton
->setPushed(state
);
432 // ***************************************************************************
433 void CInterfaceHelp::setKeepMode(uint i
, bool state
)
435 if(i
<_InfoWindows
.size())
437 _InfoWindows
[i
].KeepMode
= state
;
438 if(_InfoWindows
[i
].KeepButton
)
439 _InfoWindows
[i
].KeepButton
->setPushed(state
);
444 // ***************************************************************************
445 void CInterfaceHelp::closeAll()
447 // update WindowList if possible
449 sint maxHelpWindow
= (sint
)_InfoWindows
.size();
451 _ActiveWindows
.clear();
453 for(uint i
=0;i
<(uint
)maxHelpWindow
;i
++)
455 _InfoWindows
[i
].Window
->setActive(false);
460 // ***************************************************************************
461 void CInterfaceHelp::resetWindowPos(sint y
)
463 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
465 // update WindowList if possible
467 sint maxHelpWindow
= (sint
)_InfoWindows
.size();
470 CViewRenderer::getInstance()->getScreenSize(w
,h
);
472 // For all windows, reset pos
473 for(uint i
=0;i
<(uint
)maxHelpWindow
;i
++)
475 _InfoWindows
[i
].Window
->setX(i
*_InfoWindows
[i
].Window
->getW(false));
476 _InfoWindows
[i
].Window
->setY((sint
)h
+y
);
477 _InfoWindows
[i
].Window
->invalidateCoords();
481 // ***************************************************************************
482 void CInterfaceHelp::serialInfoWindows(NLMISC::IStream
&f
)
486 vector
<CInfoWindowSave
> infoWindowSave
;
489 // Setup pos by default (for case where number of windows differ)
490 resetWindowPos(-100);
492 f
.serialCont(infoWindowSave
);
493 uint minSize
= (uint
)min(infoWindowSave
.size(), _InfoWindows
.size());
494 for(uint i
=0;i
<minSize
;i
++)
496 _InfoWindows
[i
].Window
->setX(infoWindowSave
[i
].X
);
497 _InfoWindows
[i
].Window
->setY(infoWindowSave
[i
].Y
);
498 _InfoWindows
[i
].Window
->invalidateCoords();
503 infoWindowSave
.resize(_InfoWindows
.size());
504 for(uint i
=0;i
<infoWindowSave
.size();i
++)
506 infoWindowSave
[i
].X
= _InfoWindows
[i
].Window
->getX();
507 infoWindowSave
[i
].Y
= _InfoWindows
[i
].Window
->getY();
509 f
.serialCont(infoWindowSave
);
513 // ***************************************************************************
514 void CInterfaceHelp::debugOpenedInfoWindows()
516 for(uint i
=0;i
<_ActiveWindows
.size();i
++)
518 uint index
= _ActiveWindows
[i
];
520 if(_InfoWindows
[index
].CtrlSheet
)
521 sheetId
= _InfoWindows
[index
].CtrlSheet
->getSheetId();
524 nlinfo("debugInfoWindow: %s", CSheetId(sheetId
).toString().c_str() );
529 // ***************************************************************************
530 void CInterfaceHelp::updateWindowSPhraseTexts()
532 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
534 for(uint i
=0;i
<_ActiveWindows
.size();i
++)
536 uint index
= _ActiveWindows
[i
];
537 CDBCtrlSheet
*ctrl
= _InfoWindows
[index
].CtrlSheet
;
538 CInterfaceGroup
*group
= _InfoWindows
[index
].Window
;
539 if(group
&& ctrl
&& (ctrl
->isSPhraseId() || ctrl
->isSPhrase()) )
541 CSheetHelpSetup setup
;
542 setup
.setupDefaultIDs();
543 setup
.HelpWindow
= group
;
544 setup
.SrcSheet
= ctrl
;
545 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getCtrl("ctrl_slot"));
547 if(ctrl
->isSPhraseId())
549 // reset up the complete window
550 setupSabrinaPhraseHelp(setup
, pPM
->getPhrase(ctrl
->getSPhraseId()), 0);
552 else if(ctrl
->isSPhrase())
555 uint32 phraseSheetId
= setup
.SrcSheet
->getSheetId();
556 pPM
->buildPhraseFromSheet(phrase
, phraseSheetId
);
557 setupSabrinaPhraseHelp(setup
, phrase
, phraseSheetId
);
563 // ***************************************************************************
564 /** Close all the helps.
566 class CHandlerCloseHelp
: public IActionHandler
568 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
570 CInterfaceHelp::closeAll();
573 REGISTER_ACTION_HANDLER( CHandlerCloseHelp
, "close_help");
576 // ***************************************************************************
577 /** Build the help window for an item and open it.
579 class CHandlerOpenItemHelp
: public IActionHandler
581 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
583 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
584 if (cs
!= NULL
&& cs
->getSheetId()!=0 )
586 // get the forceKeep param (for Building info)
587 sint forceKeepWindow
= -1;
588 string forceKeepWindowStr
= getParam(sParams
, "force_keep");
589 if(!forceKeepWindowStr
.empty())
590 fromString(forceKeepWindowStr
, forceKeepWindow
);
592 // open the next window
593 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
, forceKeepWindow
);
595 CSheetHelpSetup setup
;
596 setup
.setupDefaultIDs();
597 setup
.HelpWindow
= group
;
599 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getElement(group
->getId()+":content:ctrl_slot"));
600 setupItemHelp(setup
);
604 REGISTER_ACTION_HANDLER( CHandlerOpenItemHelp
, "open_item_help");
607 // ***************************************************************************
608 /** Build the help window for a pact and open it.
610 class CHandlerOpenPactHelp
: public IActionHandler
612 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
614 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
615 if (cs
!= NULL
&& cs
->getSheetId()!=0 )
617 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
);
619 CSheetHelpSetup setup
;
620 setup
.setupDefaultIDs();
621 setup
.HelpWindow
= group
;
623 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getElement(group
->getId()+":content:ctrl_slot"));
624 setupPactHelp(setup
);
628 REGISTER_ACTION_HANDLER( CHandlerOpenPactHelp
, "open_pact_help");
631 // ***************************************************************************
632 /** Build the help window for a targeted entity to know what the title means
634 class CHandlerOpenTitleHelp
: public IActionHandler
636 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
638 // display web profile if necessary
639 if (getParam(sParams
, "from") == "contact")
644 CInterfaceGroup
*fatherGC
= pCaller
->getParent();
645 if (fatherGC
== NULL
)
647 fatherGC
= fatherGC
->getParent();
648 if (fatherGC
== NULL
)
650 string str
= fatherGC
->getId().substr(0,fatherGC
->getId().rfind('_'));
651 str
= str
.substr(str
.rfind(':')+1, str
.size());
652 CPeopleList
*peopleList
= PeopleInterraction
.getPeopleListFromContainerID(str
);
653 if (peopleList
== NULL
)
656 sint index
= peopleList
->getIndexFromContainerID(fatherGC
->getId());
659 string name
= peopleList
->getName(index
);
662 CAHManager::getInstance()->runActionHandler("show_hide", pCaller
, "profile|pname="+name
+"|ptype="+toString((int)CEntityCL::Player
));
666 else if (getParam(sParams
, "from") == "target")
668 // Require info on the target
669 CEntityCL
*selection
= EntitiesMngr
.entity(UserEntity
->selection());
670 if (selection
== NULL
) return;
671 //if(selection->isNPC())
673 string name
= selection
->getEntityName();
676 // try to get the name from the string manager (for npc)
677 uint32 nDBid
= selection
->getNameId();
680 STRING_MANAGER::CStringManagerClient
*pSMC
= STRING_MANAGER::CStringManagerClient::instance();
681 pSMC
->getString (nDBid
, name
);
682 string copyName
= name
;
683 name
= CEntityCL::removeTitleAndShardFromName(name
);
686 CCharacterCL
*pChar
= dynamic_cast<CCharacterCL
*>(selection
);
689 woman
= pChar
->getGender() == GSGENDER::female
;
691 // extract the replacement id
692 string strNewTitle
= CEntityCL::getTitleFromName(copyName
);
694 // retrieve the translated string
695 if (!strNewTitle
.empty())
696 name
= STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(strNewTitle
, woman
);
703 CAHManager::getInstance()->runActionHandler("show_hide", pCaller
, "profile|pname="+name
+"|ptype="+toString((int)selection
->Type
));
708 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(NULL
);
711 // prepare the help window
712 CSheetHelpSetup setup
;
713 setup
.setupDefaultIDs();
714 setup
.HelpWindow
= group
;
715 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getElement(group
->getId()+":content:ctrl_slot"));
717 // Get name and title
718 // ------------------
721 bool reservedTitle
= false;
722 string sFrom
= getParam(sParams
, "from");
723 if (sFrom
== "target")
725 // Require info on the target
726 CEntityCL
*selection
= EntitiesMngr
.entity(UserEntity
->selection());
727 if (selection
== NULL
) return;
728 name
= CEntityCL::removeTitleAndShardFromName(selection
->getEntityName());
729 title
= selection
->getTitle();
730 reservedTitle
= selection
->hasReservedTitle();
732 else if (sFrom
== "user")
734 // Require info on the local_player
735 name
= CEntityCL::removeTitleAndShardFromName(UserEntity
->getEntityName());
736 title
= UserEntity
->getTitle();
737 reservedTitle
= UserEntity
->hasReservedTitle();
741 // Get Title info (bricks and skills needed)
742 // -----------------------------------------
743 CUnblockTitlesSheet
*pUTS
= dynamic_cast<CUnblockTitlesSheet
*>(SheetMngr
.get(CSheetId("unblock.titles")));
746 nlwarning("cant find unblock.titles");
750 // get title id number from the title id
752 for (titleIDnb
= 0; titleIDnb
< CHARACTER_TITLE::NB_CHARACTER_TITLE
; ++titleIDnb
)
754 bool women
= UserEntity
&& UserEntity
->getGender()==GSGENDER::female
;
755 if (CStringManagerClient::getTitleLocalizedName(CHARACTER_TITLE::toString((CHARACTER_TITLE::ECharacterTitle
)titleIDnb
),women
) == title
)
759 // Retrieve all infos about the title
760 const CUnblockTitlesSheet::STitleUnblock
*pTU
= NULL
;
761 if (titleIDnb
!= CHARACTER_TITLE::NB_CHARACTER_TITLE
)
762 pTU
= &pUTS
->TitlesUnblock
[titleIDnb
];
765 // Display all infos found
766 // -----------------------
767 string titleText
= CI18N::get("uihelpTitleFormat");
768 strFindReplace(titleText
, "%name", name
);
771 string::size_type p1
= title
.find('(');
772 if (p1
!= string::npos
)
774 string::size_type p2
= title
.find(')', p1
+1);
775 if (p2
!= string::npos
)
776 title
= title
.substr(p1
+1, p2
-p1
-1);
778 strFindReplace(titleText
, "%title", title
);
780 // Display all skills needed to obtain this title
781 string sSkillsNeeded
;
782 if (!title
.empty() && pTU
== NULL
)
783 sSkillsNeeded
= CI18N::get("uiTitleCantObtain");
787 sSkillsNeeded
= CI18N::get("uiTitleSkillHeader");
788 if (pTU
->SkillsNeeded
.empty() || reservedTitle
)
790 sSkillsNeeded
+= CI18N::get("uiTitleSkillNoNeed");
794 for (uint i
= 0; i
< pTU
->SkillsNeeded
.size(); ++i
)
796 for (uint j
= 0; j
< pTU
->SkillsNeeded
[i
].size(); ++j
)
799 for (skillNb
= 0; skillNb
< SKILLS::NUM_SKILLS
; ++skillNb
)
800 if (pTU
->SkillsNeeded
[i
][j
] == SKILLS::toString((SKILLS::ESkills
)skillNb
))
803 if (skillNb
!= SKILLS::NUM_SKILLS
)
805 sSkillsNeeded
+= CStringManagerClient::getSkillLocalizedName((SKILLS::ESkills
)skillNb
);
806 sSkillsNeeded
+= " (" + toString(pTU
->SkillsLevelNeeded
[i
][j
]) + ")";
807 sSkillsNeeded
+= "\n";
811 nlwarning("cant find skill : %s", pTU
->SkillsNeeded
[i
][j
].c_str());
814 if( i
!= pTU
->SkillsNeeded
.size()-1 )
816 sSkillsNeeded
+= CI18N::get("uiTitleSkillOr");
817 sSkillsNeeded
+="\n";
822 strFindReplace(titleText
, "%skills", sSkillsNeeded
);
824 // Display all bricks needed to obtain this title
825 string sBricksNeeded
;
828 sBricksNeeded
= CI18N::get("uiTitleBrickHeader");
829 if (pTU
->BricksNeeded
.empty() || reservedTitle
)
831 sBricksNeeded
+= CI18N::get("uiTitleBrickNoNeed");
835 // Get the list of "requirement bricks"
836 string listID
= group
->getId() + setup
.PrefixForExtra
+ INFO_LIST_BRICK_REQUIREMENT
;
837 IListSheetBase
*listBrick
= dynamic_cast<IListSheetBase
*>(group
->getElement(listID
));
841 phrase
.Bricks
= pTU
->BricksNeeded
;
842 fillSabrinaPhraseListBrick(phrase
, listBrick
);
846 strFindReplace(titleText
, "%bricks", sBricksNeeded
);
849 setHelpText(setup
, titleText
);
850 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpTitleInfo"));
852 // hide the ctrl sheet
853 setHelpCtrlSheet(setup
, 0);
857 REGISTER_ACTION_HANDLER( CHandlerOpenTitleHelp
, "open_title_help");
859 // ***************************************************************************
860 /** Build the help for a skill that is to trade
862 class CHandlerOpenSkillToTradeHelp
: public IActionHandler
864 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
866 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
869 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
);
871 CSheetHelpSetup setup
;
872 setup
.setupDefaultIDs();
873 setup
.HelpWindow
= group
;
875 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getElement(group
->getId()+":content:ctrl_slot"));
876 setupSkillToTradeHelp(setup
);
880 REGISTER_ACTION_HANDLER( CHandlerOpenSkillToTradeHelp
, "open_skill_to_trade_help");
882 // ***************************************************************************
883 /** Build the help window for a pact/item/brick and open it.
885 class CHandlerOpenHelpAuto
: public IActionHandler
887 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
889 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
892 nlwarning("<CHandlerOpenHelpAuto::execute> no caller sheet found.");
895 if (cs
->getSheetId()!=0 )
897 // create group to display help
898 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
);
901 CSheetHelpSetup setup
;
902 setup
.setupDefaultIDs();
903 setup
.HelpWindow
= group
;
905 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getElement(group
->getId()+":content:ctrl_slot"));
906 setupSheetHelp(setup
);
910 REGISTER_ACTION_HANDLER( CHandlerOpenHelpAuto
, "open_help_auto");
912 // ***************************************************************************
913 /** Browse an URL into a CGroupHTML
915 class CHandlerBrowse
: public IActionHandler
917 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
919 string container
= getParam (sParams
, "name");
920 CInterfaceElement
*element
= CWidgetManager::getInstance()->getElementFromId(container
);
921 CInterfaceGroup
*elementGroup
= dynamic_cast<CInterfaceGroup
*>(element
);
923 string urls
= getParam (sParams
, "url");
925 bool show
= getParam (sParams
, "show") != "0";
927 bool localizePage
= getParam (sParams
, "localize")=="1";
930 if (strncmp (urls
.c_str(), "ah:", 3) == 0)
932 // Find next action handler
933 string::size_type start
= 3;
934 string::size_type end
= urls
.find ("&&", start
);
935 if (end
== string::npos
)
940 string url
= urls
.substr(start
, end
-start
);
942 // Run an action handler
943 string::size_type index
= url
.find_first_of("&");
944 if (index
== string::npos
)
946 string action
= url
.substr(0, index
);
948 if (index
<url
.size())
949 params
= url
.substr(index
+1, url
.size()-index
-1);
952 if(action
=="command")
956 while ((index
= params
.find_first_of("&", index
)) != string::npos
)
965 while ((index
= params
.find_first_of("&", index
)) != string::npos
)
971 // Replace %HH encoding with ASCII values (AFTER '&' replacing, to possibly have reals '&')
972 for(uint i
=0;i
<params
.size();i
++)
974 if(params
[i
]=='%' && i
<params
.size()-2)
976 if(isxdigit(params
[i
+1]) && isxdigit(params
[i
+2])) // FIXME: Locale dependent
978 // read value from heax decimal
980 params
[i
+1]= tolower(params
[i
+1]); // FIXME: toLowerAscii
981 params
[i
+2]= tolower(params
[i
+2]); // FIXME: toLowerAscii
982 if(isdigit(params
[i
+1])) val
= params
[i
+1]-'0';
983 else val
= 10+ params
[i
+1]-'a';
985 if(isdigit(params
[i
+2])) val
+= params
[i
+2]-'0';
986 else val
+= 10+ params
[i
+2]-'a';
991 params
.erase(i
+1, 2);
996 CInterfaceManager::parseTokens(params
);
997 // go. NB: the action handler himself may translate params from utf8
998 CAHManager::getInstance()->runActionHandler(action
, elementGroup
, params
);
1002 end
= urls
.find ("&&", start
);
1003 if (end
== string::npos
)
1009 // Get the group HTML
1013 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(element
);
1018 // Look for a parent container
1019 CInterfaceGroup
*parent
= groupHtml
->getParent();
1022 if (parent
->getParent() && (parent
->getParent()->getId() == "ui:interface"))
1024 parent
->setActive(true);
1028 parent
= parent
->getParent();
1032 // localize if wanted
1034 strFindReplace(urls
, "_wk.", string("_")+ClientCfg
.getHtmlLanguageCode()+"." );
1037 groupHtml
->browse(urls
.c_str());
1038 // Set top of the page
1039 CCtrlScroll
*pScroll
= groupHtml
->getScrollBar();
1040 if (pScroll
!= NULL
)
1041 pScroll
->moveTrackY(10000);
1047 REGISTER_ACTION_HANDLER( CHandlerBrowse
, "browse");
1049 // ***************************************************************************
1050 /** Browse Undo into a CGroupHTML
1052 class CHandlerBrowseUndo
: public IActionHandler
1055 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
1057 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1058 string container
= getParam (sParams
, "name");
1059 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId(container
));
1062 groupHtml
->browseUndo();
1066 REGISTER_ACTION_HANDLER( CHandlerBrowseUndo
, "browse_undo");
1068 // ***************************************************************************
1069 /** Browse Redo into a CGroupHTML
1071 class CHandlerBrowseRedo
: public IActionHandler
1074 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
1076 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1077 string container
= getParam (sParams
, "name");
1078 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId(container
));
1081 groupHtml
->browseRedo();
1085 REGISTER_ACTION_HANDLER( CHandlerBrowseRedo
, "browse_redo");
1087 // ***************************************************************************
1088 /** Browse Redo into a CGroupHTML
1090 class CHandlerBrowseRefresh
: public IActionHandler
1093 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
1095 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1096 string container
= getParam (sParams
, "name");
1097 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId(container
));
1100 groupHtml
->refresh();
1104 REGISTER_ACTION_HANDLER( CHandlerBrowseRefresh
, "browse_refresh");
1108 // ***************************************************************************
1109 class CHandlerHTMLSubmitForm
: public IActionHandler
1111 void execute (CCtrlBase
*pCaller
, const string
&sParams
)
1113 string container
= getParam (sParams
, "name");
1116 if (!fromString(getParam(sParams
, "button"), button
))
1118 nlwarning("Invalid button index: '%s', expected integer", getParam(sParams
, "button").c_str());
1122 sint32 x
= pCaller
? pCaller
->getEventX() : 0;
1123 sint32 y
= pCaller
? pCaller
->getEventY() : 0;
1125 CInterfaceElement
*element
= CWidgetManager::getInstance()->getElementFromId(container
);
1128 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(element
);
1131 groupHtml
->submitForm(button
, x
, y
);
1135 nlwarning("CGroupHTML with id '%s' not found.", container
.c_str());
1140 REGISTER_ACTION_HANDLER( CHandlerHTMLSubmitForm
, "html_submit_form");
1142 //////////////////////////////////
1143 // STATIC FUNCTIONS DEFINITIONS //
1144 //////////////////////////////////
1146 // ***************************************************************************
1147 static void setupHelpPage(CInterfaceGroup
*window
, const string
&url
)
1149 // must be a container
1150 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(window
);
1152 gc
->setHelpPage(url
);
1155 // ***************************************************************************
1156 void setHelpText(CSheetHelpSetup
&setup
, const string
&text
)
1158 string copyStr
= text
;
1159 // remove trailing \n
1160 while(!copyStr
.empty() && copyStr
[copyStr
.size()-1]=='\n')
1162 copyStr
.resize(copyStr
.size()-1);
1165 if (!setup
.HelpWindow
) return;
1166 CViewText
*viewText
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getView(setup
.ViewText
));
1169 viewText
->setTextFormatTaged(copyStr
);
1171 CInterfaceGroup
*viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextGroup
);
1172 if (viewTextGroup
) viewTextGroup
->setActive(true);
1173 if (!setup
.ScrollTextIdGroup
.empty())
1175 viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextIdGroup
);
1176 if (viewTextGroup
) viewTextGroup
->setActive(false);
1180 // ***************************************************************************
1181 void setHelpCtrlSheet(CSheetHelpSetup
&setup
, uint32 sheetId
)
1184 setup
.DestSheet
->setSheetId (sheetId
);
1187 // ***************************************************************************
1188 void setHelpTextID(CSheetHelpSetup
&setup
, sint32 id
)
1190 if (!setup
.HelpWindow
) return;
1191 CViewTextID
*viewTextID
= dynamic_cast<CViewTextID
*>(setup
.HelpWindow
->getView(setup
.ViewTextID
));
1194 viewTextID
->setTextId(id
);
1196 if (!setup
.ScrollTextGroup
.empty())
1198 CInterfaceGroup
*viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextGroup
);
1199 if (viewTextGroup
) viewTextGroup
->setActive(false);
1201 CInterfaceGroup
*viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextIdGroup
);
1202 if (viewTextGroup
) viewTextGroup
->setActive(true);
1205 // ***************************************************************************
1206 static void setupHelpTitle(CInterfaceGroup
*group
, const string
&title
)
1208 CGroupContainer
*pGC
= dynamic_cast<CGroupContainer
*>(group
);
1211 pGC
->setTitle(title
);
1214 // ***************************************************************************
1215 static void setupSkillToTradeHelp(CSheetHelpSetup
&setup
)
1217 if (!setup
.HelpWindow
) return;
1219 // get the calling item
1220 if (!setup
.SrcSheet
)
1222 nlwarning("<CHandlerOpenBrickHelp::execute> no caller sheet found.");
1226 SKILLS::ESkills skill
= setup
.SrcSheet
->getSkill();
1227 if (skill
>= SKILLS::unknown
)
1229 nlwarning("bad skill");
1236 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
1237 setup
.DestSheet
->setActive(true);
1243 const char *title
= CStringManagerClient::getSkillLocalizedName(skill
);
1244 setupHelpTitle(setup
.HelpWindow
, title
);
1246 // search all job that have minimum required level for that skill
1247 // CInterfaceManager *im = CInterfaceManager::getInstance();
1248 // for (uint career = 0; career < JOBS::NUM_CAREER_DB_SLOTS; ++career)
1250 // for (uint job = 0; job < 8; ++job)
1252 // string dbPath = toString("CHARACTER_INFO:CAREER%d:JOB%d:JOB_CAP", (int) career, (int) job);
1253 // uint level = (uint) NLGUI::CDBManager::getInstance()->getDbProp(dbPath)->getValue32();
1254 // if (level != 0) // has the player this job ?
1256 // // check if level in this job is enough to get the skills
1257 // // TODO finish it
1259 // JOBS::TJob job = JOBS::getJobFromDBIndex(career, job);
1260 // if (job != JOBS::Unknown)
1267 // setup skill desc if available.
1268 const char *desc
= CStringManagerClient::getSkillLocalizedDescription(skill
);
1275 setHelpText(setup
, skillText
);
1279 // ***************************************************************************
1280 static string
toReadableFloat(float val
)
1282 sint iv
= sint(val
* 10);
1285 return toString(iv
/10);
1289 return toString("%.1f", val
);
1293 // ***************************************************************************
1294 static string
toPercentageText(float val
)
1296 sint iv
= sint(val
* 1000);
1299 return toString(iv
/10);
1304 return toString("%.1f", val
);
1308 // ***************************************************************************
1309 void getItemDefenseText(CDBCtrlSheet
*item
, string
&itemText
)
1311 // retrieve the current itemInfo
1312 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1315 strFindReplace(itemText
, "%dodge", toString(itemInfo
.DodgeModifier
) );
1316 strFindReplace(itemText
, "%parry", toString(itemInfo
.ParryModifier
) );
1318 // Display All protections
1319 strFindReplace( itemText
, "%protect", toPercentageText(itemInfo
.ProtectionFactor
) );
1320 strFindReplace( itemText
, "%p_slash", toString(itemInfo
.MaxSlashingProtection
) );
1321 strFindReplace( itemText
, "%p_pierce", toString(itemInfo
.MaxPiercingProtection
) );
1322 strFindReplace( itemText
, "%p_blunt", toString(itemInfo
.MaxBluntProtection
) );
1326 void getDamageText(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
, bool displayAsMod
)
1328 // retrieve the current itemInfo
1329 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1334 strFindReplace(itemText
, "%dmg", strMod
+ toString(itemInfo
.CurrentDamage
));
1337 strFindReplace(itemText
, "%max_dmg", strMod
+ toString(itemInfo
.MaxDamage
));
1339 if(pIS
->Family
!=ITEMFAMILY::AMMO
)
1341 // Display the Dodge/Parry Modifier
1342 strFindReplace(itemText
, "%dodge", toString(itemInfo
.DodgeModifier
) );
1343 strFindReplace(itemText
, "%parry", toString(itemInfo
.ParryModifier
) );
1345 // Display the Adversary Dodge/Parry Modifier
1346 strFindReplace(itemText
, "%adv_dodge", toString(itemInfo
.AdversaryDodgeModifier
) );
1347 strFindReplace(itemText
, "%adv_parry", toString(itemInfo
.AdversaryParryModifier
) );
1351 void getSpeedText(CDBCtrlSheet
*item
, string
&itemText
, bool displayAsMod
)
1353 // retrieve the current itemInfo
1354 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1358 strMod
= itemInfo
.HitRate
>=0?"+":"";
1359 strFindReplace(itemText
, "%speed", strMod
+ toReadableFloat(itemInfo
.HitRate
));
1362 void getRangeText(CDBCtrlSheet
*item
, string
&itemText
, bool displayAsMod
)
1364 // retrieve the current itemInfo
1365 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1369 strMod
= itemInfo
.Range
>=0?"+":"";
1370 strFindReplace(itemText
, "%range", strMod
+ toReadableFloat(itemInfo
.Range
/1000.f
));
1373 void getHPAndSapLoadText(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
)
1375 // retrieve the current itemInfo
1376 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1378 if(pIS
->Family
!= ITEMFAMILY::RAW_MATERIAL
)
1380 // must find first hpmax! (else replace error)
1381 strFindReplace(itemText
, "%hpmax", toString(itemInfo
.HpMax
) );
1382 strFindReplace(itemText
, "%hp", toString(itemInfo
.Hp
) );
1384 strFindReplace(itemText
, "%sapmax", toString(itemInfo
.SapLoadMax
) );
1385 strFindReplace(itemText
, "%sap", toString(itemInfo
.SapLoadCurrent
) );
1390 void getBuffText(CDBCtrlSheet
*item
, string
&itemText
)
1392 // retrieve the current itemInfo
1393 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1395 const string valIds
[]={"Hp", "Sap", "Sta", "Focus"};
1396 sint32 vals
[]= {itemInfo
.HpBuff
, itemInfo
.SapBuff
, itemInfo
.StaBuff
, itemInfo
.FocusBuff
};
1397 uint numVals
= sizeof(vals
) / sizeof(vals
[0]);
1400 // For each buf, append a line if !=0
1401 for(uint i
=0;i
<numVals
;i
++)
1403 sint32 modifier
= vals
[i
];
1406 string line
= CI18N::get( "uihelpItem" + valIds
[i
] + (modifier
>0?"Bonus":"Malus") );
1407 strFindReplace(line
, "%val", toString(modifier
) );
1412 // append a \n before
1413 if(!bufInfo
.empty())
1414 bufInfo
= "\n" + bufInfo
+ "\n";
1416 // Display the buff info.
1417 strFindReplace(itemText
, "%buffs", bufInfo
);
1420 void getMagicProtection(CDBCtrlSheet
*item
, string
&itemText
)
1422 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1423 // retrieve the current itemInfo
1424 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1428 // Header (always here, because at least max absorb)
1429 mProtInfo
= CI18N::get("uihelpMagicProtectFormatHeader");
1431 // For each protection
1432 for(uint i
=0;i
<CClientItemInfo::MaxMagicProtectionByJewel
;i
++)
1434 if(itemInfo
.MagicProtection
[i
] != PROTECTION_TYPE::None
)
1437 string str
= CI18N::get("uihelpMagicProtectFormat");
1438 strFindReplace(str
, "%t", CI18N::get("pt"+PROTECTION_TYPE::toString(itemInfo
.MagicProtection
[i
])) );
1439 strFindReplace(str
, "%v", toString(itemInfo
.MagicProtectionFactor
[i
]) );
1444 // add Max damage absorbed
1446 // Mul item quality by a constant
1447 uint maxAbsorb
= item
->getQuality();
1448 CCDBNodeLeaf
*nodeFactor
= NLGUI::CDBManager::getInstance()->getDbProp(CWidgetManager::getInstance()->getParser()->getDefine("player_protect_absorbfactor"), false);
1450 maxAbsorb
= maxAbsorb
*nodeFactor
->getValue32()/100;
1453 string str
= CI18N::get("uihelpMagicProtectMaxAbsorbFormat");
1454 strFindReplace(str
, "%v", toString(maxAbsorb
) );
1458 // replace in item info
1459 strFindReplace(itemText
, "%magic_protection", mProtInfo
);
1462 void getMagicResistance(CDBCtrlSheet
*item
, string
&itemText
)
1464 // retrieve the current itemInfo
1465 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1469 // Header (always here, because at least max absorb)
1470 mResistInfo
= CI18N::get("uihelpMagicResistFormatHeader");
1472 // For each resistance
1473 uint32 resist
[RESISTANCE_TYPE::NB_RESISTANCE_TYPE
];
1474 nlctassert(RESISTANCE_TYPE::NB_RESISTANCE_TYPE
==5);
1475 resist
[RESISTANCE_TYPE::Desert
]= itemInfo
.DesertMagicResistance
;
1476 resist
[RESISTANCE_TYPE::Forest
]= itemInfo
.ForestMagicResistance
;
1477 resist
[RESISTANCE_TYPE::Lacustre
]= itemInfo
.LacustreMagicResistance
;
1478 resist
[RESISTANCE_TYPE::Jungle
]= itemInfo
.JungleMagicResistance
;
1479 resist
[RESISTANCE_TYPE::PrimaryRoot
]= itemInfo
.PrimaryRootMagicResistance
;
1480 for(uint i
=0;i
<RESISTANCE_TYPE::NB_RESISTANCE_TYPE
;i
++)
1485 string str
= CI18N::get("uihelpMagicResistFormat");
1486 strFindReplace(str
, "%t", CI18N::get("rs"+RESISTANCE_TYPE::toString((RESISTANCE_TYPE::TResistanceType
)i
) ));
1487 strFindReplace(str
, "%v", toReadableFloat(float(resist
[i
])/100) );
1492 // replace in item info
1493 strFindReplace(itemText
, "%magic_resistance", mResistInfo
);
1496 void getActionMalus(CDBCtrlSheet
*item
, string
&itemText
)
1498 // retrieve the current itemInfo
1499 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1501 strFindReplace(itemText
, "%actmalus", toPercentageText(itemInfo
.WearEquipmentMalus
) );
1504 void getBulkText(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
)
1506 // Display direct value: because cannot know where this item will be drop!! (bag, mektoub etc...)
1507 float slotBulkTotal
= max((sint32
)1, item
->getQuantity()) * pIS
->Bulk
;
1509 // If stackable and bulk not 0, display in form "1 (10)". where (10) is the total of quantity*bulk
1510 if(pIS
->Stackable
>1 && pIS
->Bulk
>0)
1511 strFindReplace(itemText
, "%bulk", toString("%.2f (%.2f)", pIS
->Bulk
, slotBulkTotal
) );
1514 strFindReplace(itemText
, "%bulk", toString("%.2f", slotBulkTotal
) );
1517 void getWeightText(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
)
1519 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1521 CCDBNodeLeaf
*pWG
= NLGUI::CDBManager::getInstance()->getDbProp(item
->getSheet()+":WEIGHT",false);
1524 // must mul weight by quantity
1525 sint32 slotWeight
= pWG
->getValue32();
1526 sint32 slotWeightTotal
= max((sint32
)1, item
->getQuantity()) * slotWeight
;
1528 // if stackable and weight not 0, display in form "1 (10)". where (10) is the total of quantity*weight
1529 if(pIS
->Stackable
>1 && slotWeight
>0)
1533 if( (slotWeight
%DB_WEIGHT_SCALE
) == 0) sws
= toString("%d", slotWeight
/DB_WEIGHT_SCALE
);
1534 else sws
= toString("%.2f", float(slotWeight
)/DB_WEIGHT_SCALE
);
1535 if( (slotWeightTotal
%DB_WEIGHT_SCALE
) == 0) swt
= toString("%d", slotWeightTotal
/DB_WEIGHT_SCALE
);
1536 else swt
= toString("%.2f", float(slotWeightTotal
)/DB_WEIGHT_SCALE
);
1539 strFindReplace(itemText
, "%weight", toString("%s (%s)", sws
.c_str(), swt
.c_str() ));
1541 // else display in simple form
1544 if( (slotWeightTotal
%DB_WEIGHT_SCALE
) == 0)
1545 strFindReplace(itemText
, "%weight", toString("%d", slotWeightTotal
/DB_WEIGHT_SCALE
));
1547 strFindReplace(itemText
, "%weight", toString("%.2f", float(slotWeightTotal
)/DB_WEIGHT_SCALE
) );
1551 strFindReplace(itemText
, "%weight", "???" );
1554 void getMagicBonus(CDBCtrlSheet
*item
, string
&itemText
)
1556 // retrieve the current itemInfo
1557 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1559 nlctassert(CClientItemInfo::NumMagicFactorType
==4);
1560 const string valIds
[CClientItemInfo::NumMagicFactorType
]={"OffElemental", "OffAffliction", "DefHeal", "DefAffliction"};
1563 // For each magic bonus, test first if equal
1564 sint32 allCastSpeedFactor
= sint(itemInfo
.CastingSpeedFactor
[0]*100);
1565 sint32 allMagicPowerFactor
= sint(itemInfo
.MagicPowerFactor
[0]*100);
1567 for(uint i
=1;i
<CClientItemInfo::NumMagicFactorType
;i
++)
1569 sint32 cs
= sint(itemInfo
.CastingSpeedFactor
[i
]*100);
1570 sint32 mp
= sint(itemInfo
.MagicPowerFactor
[i
]*100);
1571 if( cs
!=allCastSpeedFactor
||
1572 mp
!=allMagicPowerFactor
)
1582 // if 0, just display nothing
1583 if(allCastSpeedFactor
!=0 || allMagicPowerFactor
!=0)
1585 // else display "all"
1586 string line
= CI18N::get( "uihelpItemMagicBonusAll");
1587 strFindReplace(line
, "%cs", toString("%+d", allCastSpeedFactor
) );
1588 strFindReplace(line
, "%mp", toString("%+d", allMagicPowerFactor
) );
1594 // then display info separated for each
1595 for(uint i
=0;i
<CClientItemInfo::NumMagicFactorType
;i
++)
1597 sint32 cs
= sint(itemInfo
.CastingSpeedFactor
[i
]*100);
1598 sint32 mp
= sint(itemInfo
.MagicPowerFactor
[i
]*100);
1601 string line
= CI18N::get( string("uihelpItemMagicBonus") + valIds
[i
] );
1602 strFindReplace(line
, "%cs", toString("%+d", cs
) );
1603 strFindReplace(line
, "%mp", toString("%+d", mp
) );
1609 // append a \n before
1612 // add spell level header
1613 string spellRuleFmt
= CI18N::get("uihelpItemMagicBonusHeader");
1614 strFindReplace(spellRuleFmt
, "%mglvl", toString(item
->getQuality()));
1615 mbInfo
= spellRuleFmt
+ mbInfo
;
1618 // Display the buff info.
1619 strFindReplace(itemText
, "%magic_bonus", mbInfo
);
1622 void getItemRequirementText(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
)
1624 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1625 bool requiredNeeded
= false;
1628 // retrieve the current itemInfo
1629 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1631 if( itemInfo
.RequiredCharac
!= CHARACTERISTICS::Unknown
&& itemInfo
.RequiredCharacLevel
!= 0 )
1633 // Build the req string
1634 if(pIM
->isItemCaracRequirementMet(itemInfo
.RequiredCharac
, (sint32
)itemInfo
.RequiredCharacLevel
))
1635 fmtc
= CI18N::get("uihelpItemCaracReqMetFmt");
1637 fmtc
= CI18N::get("uihelpItemCaracReqNotMetFmt");
1638 strFindReplace(fmtc
, "%d", toString((uint
)itemInfo
.RequiredCharacLevel
));
1639 strFindReplace(fmtc
, "%s", CI18N::get(toString("uiCaracId%d", (uint
)itemInfo
.RequiredCharac
)) );
1641 //strFindReplace(itemText, "%caracreq", fmtc );
1642 requiredNeeded
= true;
1646 //strFindReplace(itemText, "%caracreq", "" );
1649 if( itemInfo
.RequiredSkillLevel
> 0 )
1651 if( itemInfo
.RequiredSkill
!= SKILLS::unknown
)
1653 if (CSkillManager::getInstance()->checkBaseSkillMetRequirement(itemInfo
.RequiredSkill
, itemInfo
.RequiredSkillLevel
))
1654 fmt
= CI18N::get("uihelpItemSkillReqMetFmt");
1656 fmt
= CI18N::get("uihelpItemSkillReqNotMetFmt");
1658 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.RequiredSkillLevel
));
1659 const char *skillName
= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName(itemInfo
.RequiredSkill
);
1660 strFindReplace(fmt
, "%s", skillName
);
1664 if (CSkillManager::getInstance()->checkBaseSkillMetRequirement(SKILLS::unknown
, itemInfo
.RequiredSkillLevel
))
1665 fmt
= CI18N::get("uihelpItemAnySkillReqMetFmt");
1667 fmt
= CI18N::get("uihelpItemAnySkillReqNotMetFmt");
1669 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.RequiredSkillLevel
));
1672 strFindReplace(itemText
, "%skillreq", fmt
);
1673 requiredNeeded
= true;
1677 strFindReplace(itemText
, "%skillreq", "" );
1680 if( itemInfo
.RequiredSkillLevel2
> 0 )
1682 if( itemInfo
.RequiredSkill2
!= SKILLS::unknown
)
1684 if (CSkillManager::getInstance()->checkBaseSkillMetRequirement(itemInfo
.RequiredSkill2
, itemInfo
.RequiredSkillLevel2
))
1685 fmt
= CI18N::get("uihelpItemSkillReqMetFmt");
1687 fmt
= CI18N::get("uihelpItemSkillReqNotMetFmt");
1689 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.RequiredSkillLevel2
));
1690 const char *skillName
= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName(itemInfo
.RequiredSkill2
);
1691 strFindReplace(fmt
, "%s", skillName
);
1695 if (CSkillManager::getInstance()->checkBaseSkillMetRequirement(SKILLS::unknown
, itemInfo
.RequiredSkillLevel2
))
1696 fmt
= CI18N::get("uihelpItemAnySkillReqMetFmt");
1698 fmt
= CI18N::get("uihelpItemAnySkillReqNotMetFmt");
1700 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.RequiredSkillLevel2
));
1703 strFindReplace(itemText
, "%skillreq2", fmt
);
1704 requiredNeeded
= true;
1708 strFindReplace(itemText
, "%skillreq2", "" );
1711 if( requiredNeeded
)
1712 strFindReplace(itemText
, "%caracreq", fmtc
);
1714 strFindReplace(itemText
, "%caracreq", CI18N::get("uihelpItemCaracReqNone") );
1717 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1719 // retrieve the current itemInfo
1720 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1722 CHARACTERISTICS::TCharacteristics caracType
;
1723 float caracValue
= 0.f
;
1725 bool req
= pIS
->hasCharacRequirement(item
->getQuality(), caracType
, caracValue
);
1727 bool req2
= (itemInfo
.RequiredCharac
!= CHARACTERISTICS::Unknown
&& itemInfo
.MinRequiredCharacLevel
> 0);
1728 bool skillReq
= (itemInfo
.MinRequiredSkillLevel
> 0 && itemInfo
.RequiredSkill
!= SKILLS::unknown
);
1730 // check item specific req
1735 if (itemInfo
.RequiredCharac
== caracType
&& itemInfo
.MinRequiredCharacLevel
> caracValue
)
1737 caracValue
= itemInfo
.MinRequiredCharacLevel
;
1743 caracValue
= itemInfo
.MinRequiredCharacLevel
;
1744 caracType
= itemInfo
.RequiredCharac
;
1752 // Build the req string
1754 if(pIM
->isItemCaracRequirementMet(caracType
, (sint32
)caracValue
))
1755 fmt
= CI18N::get("uihelpItemCaracReqMetFmt");
1757 fmt
= CI18N::get("uihelpItemCaracReqNotMetFmt");
1758 strFindReplace(fmt
, "%d", toString((uint
)caracValue
));
1759 strFindReplace(fmt
, "%s", CI18N::get(toString("uiCaracId%d", (uint
)caracType
)) );
1763 fmt
+= CI18N::get("uihelpItemCaracReqAnd");
1764 if ( pIM
->isItemCaracRequirementMet(itemInfo
.RequiredCharac
, (sint32
)itemInfo
.MinRequiredCharacLevel
) )
1765 fmt
+= CI18N::get("uihelpItemCaracReqMetFmt");
1767 fmt
+= CI18N::get("uihelpItemCaracReqNotMetFmt");
1768 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.MinRequiredCharacLevel
));
1769 strFindReplace(fmt
, "%s", CI18N::get(toString("uiCaracId%d", (uint
)itemInfo
.RequiredCharac
)) );
1772 strFindReplace(itemText
, "%caracreq", fmt
);
1777 strFindReplace(itemText
, "%caracreq", CI18N::get("uihelpItemCaracReqNone") );
1779 else // skillReq and no charac req
1782 strFindReplace(itemText
, "%caracreq", "" );
1787 // Build the req string
1790 fmt
= CI18N::get("uihelpItemCaracReqAnd");
1792 if (CSkillManager::getInstance()->checkBaseSkillMetRequirement(itemInfo
.RequiredSkill
, itemInfo
.MinRequiredSkillLevel
))
1793 fmt
+= CI18N::get("uihelpItemSkillReqMetFmt");
1795 fmt
+= CI18N::get("uihelpItemSkillReqNotMetFmt");
1796 strFindReplace(fmt
, "%d", toString((uint
)itemInfo
.MinRequiredSkillLevel
));
1797 const char *skillName
= STRING_MANAGER::CStringManagerClient::getSkillLocalizedName(itemInfo
.RequiredSkill
);
1798 strFindReplace(fmt
, "%s", skillName
);
1800 strFindReplace(itemText
, "%skillreq", fmt
);
1804 strFindReplace(itemText
, "%skillreq", "" );
1809 void getSkillModVsType(CDBCtrlSheet
*item
, const CItemSheet
*pIS
, string
&itemText
)
1811 // retrieve the current itemInfo
1812 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1816 if(!itemInfo
.TypeSkillMods
.empty())
1818 for (uint i
= 0 ; i
< itemInfo
.TypeSkillMods
.size() ; ++i
)
1820 EGSPD::CClassificationType::TClassificationType type
= itemInfo
.TypeSkillMods
[i
].Type
;
1822 sMod
= CI18N::get("uihelpSkillModVsType");
1823 strFindReplace(sMod
, "%mod", NLMISC::toString(itemInfo
.TypeSkillMods
[i
].Modifier
));
1824 strFindReplace(sMod
, "%type", CStringManagerClient::getClassificationTypeLocalizedName(type
));
1827 // TODO : process ALL mod
1832 strFindReplace(itemText
, "%skill_mod_vs_type", sMod
);
1835 void getArmorBonus(CDBCtrlSheet
*item
, string
&itemText
, const CItemSheet
*pIS
)
1840 if (pIS
->Armor
.ArmorType
== ARMORTYPE::HEAVY
)
1841 level
= item
->getQuality();
1842 else if (pIS
->Armor
.ArmorType
== ARMORTYPE::MEDIUM
)
1843 level
= item
->getQuality() / 2;
1845 if (pIS
->Armor
.ArmorType
== ARMORTYPE::HEAVY
|| pIS
->Armor
.ArmorType
== ARMORTYPE::MEDIUM
)
1846 armor_bonus
= "@{FFFF}(+@{2F2F}" + toString(level
) + " @{FFFF}" + CI18N::get("uiHP") + ")";
1848 strFindReplace(itemText
, "%armor_bonus", armor_bonus
);
1851 // ***************************************************************************
1852 void getItemText (CDBCtrlSheet
*item
, string
&itemText
, const CItemSheet
*pIS
)
1854 if ((item
== NULL
) || (pIS
== NULL
))
1857 // *** Select the correct format according to item family.
1860 case ITEMFAMILY::ARMOR
: itemText
= CI18N::get("uihelpItemArmorFormat"); break;
1861 case ITEMFAMILY::MELEE_WEAPON
: itemText
= CI18N::get("uihelpItemMeleeWeaponFormat"); break;
1862 case ITEMFAMILY::RANGE_WEAPON
: itemText
= CI18N::get("uihelpItemRangeWeaponFormat"); break;
1863 case ITEMFAMILY::AMMO
: itemText
= CI18N::get("uihelpItemAmmoFormat"); break;
1864 case ITEMFAMILY::RAW_MATERIAL
: itemText
= CI18N::get("uihelpItemMPFormat"); break;
1865 case ITEMFAMILY::SHIELD
: itemText
= CI18N::get("uihelpItemShieldFormat"); break;
1866 case ITEMFAMILY::CRAFTING_TOOL
: itemText
= CI18N::get("uihelpItemCraftingToolFormat"); break;
1867 case ITEMFAMILY::HARVEST_TOOL
: itemText
= CI18N::get("uihelpItemHarvestToolFormat"); break;
1868 case ITEMFAMILY::TAMING_TOOL
: itemText
= CI18N::get("uihelpItemTamingToolFormat"); break;
1869 case ITEMFAMILY::JEWELRY
: itemText
= CI18N::get("uihelpItemJewelFormat"); break;
1870 case ITEMFAMILY::CRYSTALLIZED_SPELL
: itemText
= CI18N::get("uihelpItemCrystalSpell"); break;
1871 case ITEMFAMILY::ITEM_SAP_RECHARGE
: itemText
= CI18N::get("uihelpItemChargeSpell"); break;
1872 case ITEMFAMILY::PET_ANIMAL_TICKET
: itemText
= CI18N::get("uihelpItemAnimal"); break;
1873 case ITEMFAMILY::TELEPORT
: itemText
= CI18N::get("uihelpItemTeleport"); break;
1874 case ITEMFAMILY::COSMETIC
: itemText
= CI18N::get("uihelpItemCosmetic"); break;
1875 case ITEMFAMILY::SCROLL
: itemText
= CI18N::get("uihelpItemScroll"); break;
1876 case ITEMFAMILY::SCROLL_R2
: itemText
= CI18N::get("uihelpItemScrollR2"); break;
1877 case ITEMFAMILY::CONSUMABLE
: itemText
= CI18N::get("uihelpItemConsumableFormat"); break;
1878 default: itemText
= CI18N::get("uihelpItemDefaultFormat");
1882 // *** Replace Common part
1883 strFindReplace(itemText
, "%origin", CI18N::get("io"+ITEM_ORIGIN::enumToString(pIS
->ItemOrigin
)) );
1884 strFindReplace(itemText
, "%quality", toString(item
->getQuality()) );
1885 strFindReplace(itemText
, "%quantity", toString(item
->getQuantity()) );
1887 getWeightText(item
, pIS
, itemText
);
1889 getBulkText(item
, pIS
, itemText
);
1890 // Get the SapLoad...
1891 getHPAndSapLoadText(item
, pIS
, itemText
);
1892 // Get carac and skill Requirement
1893 getItemRequirementText(item
, pIS
, itemText
);
1895 CItemSpecialEffectHelper::getInstance()->getItemSpecialEffectText(pIS
, itemText
);
1898 const char *desc
= CStringManagerClient::getItemLocalizedDescription(pIS
->Id
);
1901 strFindReplace(itemText
, "%desc", "@{FFF9}" + CI18N::get("uiMissionDesc") + "\n@{FFFF}" + desc
+ "\n" );
1904 strFindReplace(itemText
, "%desc", string() );
1907 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(item
) );
1908 if (!itemInfo
.CustomText
.empty())
1910 std::string text
= itemInfo
.CustomText
.toUtf8();
1911 if (text
.size() > 3 && text
[0]=='@' && ((text
[1]=='W' && text
[2]=='E' && text
[3]=='B') || (text
[1]=='L' && text
[2]=='U' && text
[3]=='A')))
1913 strFindReplace(itemText
, "%custom_text", string() );
1917 strFindReplace(itemText
, "%custom_text", "\n@{FFFF}" + itemInfo
.CustomText
.toUtf8() + "\n");
1918 string itemMFC
= CI18N::get("uiItemTextMessageFromCrafter");
1919 strFindReplace(itemText
, "%mfc", itemMFC
);
1923 strFindReplace(itemText
, "%custom_text", string() );
1925 if ( pIS
->Family
== ITEMFAMILY::COSMETIC
)
1927 EGSPD::CPeople::TPeople people
= ITEM_ORIGIN::itemOriginStringToPeopleEnum( ITEM_ORIGIN::enumToString( pIS
->ItemOrigin
) );
1928 if ( UserEntity
->getGender() != pIS
->Cosmetic
.Gender
|| UserEntity
->people() != people
)
1929 strFindReplace(itemText
, "%cansell", CI18N::get("uihelpItemCosmeticDontFit") );
1931 strFindReplace(itemText
, "%cansell", string() );
1933 else if(pIS
->DropOrSell
)
1934 strFindReplace(itemText
, "%cansell", string() );
1936 strFindReplace(itemText
, "%cansell", CI18N::get("uihelpItemCantSell") );
1938 // *** Replace special for each type
1941 case ITEMFAMILY::ARMOR
:
1943 strFindReplace(itemText
, "%armor", CI18N::get("at"+ARMORTYPE::toString(pIS
->Armor
.ArmorType
)));
1944 // Armor bonus based on armor type
1945 getArmorBonus(item
, itemText
, pIS
);
1947 getItemDefenseText(item
, itemText
);
1949 getBuffText(item
, itemText
);
1951 getActionMalus(item
, itemText
);
1954 case ITEMFAMILY::MELEE_WEAPON
:
1956 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->MeleeWeapon
.Skill
) );
1957 strFindReplace(itemText
, "%cat", CI18N::get("wt"+WEAPONTYPE::toString(pIS
->MeleeWeapon
.WeaponType
)) );
1958 strFindReplace(itemText
, "%dmtype", CI18N::get("dt"+DMGTYPE::toString(pIS
->MeleeWeapon
.DamageType
)) );
1959 strFindReplace(itemText
, "%reach", toString(pIS
->MeleeWeapon
.MeleeRange
) );
1961 getDamageText(item
, pIS
, itemText
, false);
1962 getSpeedText(item
, itemText
, false);
1964 getBuffText(item
, itemText
);
1966 getActionMalus(item
, itemText
);
1968 getMagicBonus(item
, itemText
);
1969 // skill bonus against specific types
1970 getSkillModVsType(item
, pIS
, itemText
);
1973 case ITEMFAMILY::RANGE_WEAPON
:
1975 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->RangeWeapon
.Skill
) );
1976 strFindReplace(itemText
, "%cat", CI18N::get("wt"+WEAPONTYPE::toString(pIS
->RangeWeapon
.WeaponType
)) );
1977 // Damage / Speed / Range
1978 getDamageText(item
, pIS
, itemText
, true);
1979 getSpeedText(item
, itemText
, false);
1980 getRangeText(item
, itemText
, false);
1982 getBuffText(item
, itemText
);
1984 getActionMalus(item
, itemText
);
1986 getMagicBonus(item
, itemText
);
1987 // skill bonus against specific types
1988 getSkillModVsType(item
, pIS
, itemText
);
1991 case ITEMFAMILY::AMMO
:
1994 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->Ammo
.Skill
) ) ;
1995 strFindReplace(itemText
, "%dmtype", CI18N::get("dt"+DMGTYPE::toString(pIS
->Ammo
.DamageType
)) );
1996 // WARNING: here 999 is hardcoded because of the new global limit of stacks (999), Ammo.Magazine should not be used anymore
1997 if (item
->getUseQuantity())
1998 strFindReplace(itemText
, "%magazine", toString(item
->getQuantity()) + " / " + toString(999 /*pIS->Ammo.Magazine*/) );
2000 strFindReplace(itemText
, "%magazine", toString(999 /*pIS->Ammo.Magazine*/) );
2002 // Damage / Speed / Range
2003 getDamageText(item
, pIS
, itemText
, false);
2004 getSpeedText(item
, itemText
, true);
2005 getRangeText(item
, itemText
, true);
2008 case ITEMFAMILY::RAW_MATERIAL
:
2011 strFindReplace(itemText
, "%ecosystem", CI18N::get("ecosys"+ECOSYSTEM::toString(pIS
->Mp
.Ecosystem
)) ) ;
2012 strFindReplace(itemText
, "%family", RM_FAMILY::toLocalString(pIS
->Mp
.Family
) ) ;
2013 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->Mp
.HarvestSkill
) ) ;
2016 if( RM_COLOR::validColor(pIS
->Mp
.MpColor
) )
2017 strFindReplace(itemText
, "%mpcolor", RM_COLOR::toLocalString(pIS
->Mp
.MpColor
) ) ;
2019 strFindReplace(itemText
, "%mpcolor", "???" );
2022 if(pIS
->canBuildSomeItemPart())
2024 string fmt
= CI18N::get("uihelpItemMPCraft");
2026 pIS
->getItemPartListAsText(ipList
);
2027 strFindReplace(fmt
, "%ip", ipList
);
2028 strFindReplace(itemText
, "%craft", fmt
);
2030 // Craft Mp requirement?
2031 else if(pIS
->isUsedAsCraftRequirement())
2032 strFindReplace(itemText
, "%craft", CI18N::get("uihelpItemMPCraftRequirement"));
2035 strFindReplace(itemText
, "%craft", CI18N::get("uihelpItemMPNoCraft"));
2038 case ITEMFAMILY::SHIELD
:
2040 //strFindReplace(itemText, "%skill", CStringManagerClient::getSkillLocalizedName(SHIELDTYPE::shieldTypeToSkill(pIS->Shield.ShieldType)) );
2041 strFindReplace(itemText
, "%cat", CI18N::get("st"+SHIELDTYPE::toString(pIS
->Shield
.ShieldType
)) );
2043 getItemDefenseText(item
, itemText
);
2045 getBuffText(item
, itemText
);
2047 getActionMalus(item
, itemText
);
2050 // Crafting Tool: the skill is not valid, since depends on what is built.
2051 case ITEMFAMILY::CRAFTING_TOOL
:
2053 strFindReplace(itemText
, "%tool", CI18N::get("tool"+TOOL_TYPE::toString(pIS
->Tool
.CraftingToolType
)) );
2055 getBuffText(item
, itemText
);
2058 case ITEMFAMILY::HARVEST_TOOL
:
2060 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->Tool
.Skill
) );
2062 getBuffText(item
, itemText
);
2065 case ITEMFAMILY::TAMING_TOOL
:
2067 strFindReplace(itemText
, "%skill", CStringManagerClient::getSkillLocalizedName(pIS
->Tool
.Skill
) );
2068 strFindReplace(itemText
, "%cmdrange", toString(pIS
->Tool
.CommandRange
) );
2069 strFindReplace(itemText
, "%maxpacker", toString(pIS
->Tool
.MaxDonkey
) );
2072 case ITEMFAMILY::JEWELRY
:
2075 getBuffText(item
, itemText
);
2077 getMagicProtection(item
, itemText
);
2078 // Magic Resistances
2079 getMagicResistance(item
, itemText
);
2082 case ITEMFAMILY::CONSUMABLE
:
2084 strFindReplace(itemText
, "%consumption_time", toString(pIS
->Consumable
.ConsumptionTime
));
2085 strFindReplace(itemText
, "%overdose_timer_min", toString(pIS
->Consumable
.OverdoseTimer
/60));
2086 strFindReplace(itemText
, "%overdose_timer_sec", toString(pIS
->Consumable
.OverdoseTimer
% 60));
2087 // Get Item Consumable infos
2088 CItemConsumableEffectHelper::getInstance()->getItemConsumableEffectText(pIS
, itemText
, item
->getQuality());
2091 case ITEMFAMILY::SCROLL_R2
:
2093 strFindReplace(itemText
, "%r2_description_text", toString(itemInfo
.R2ItemDescription
));
2094 strFindReplace(itemText
, "%r2_comment_text", toString(itemInfo
.R2ItemComment
));
2097 case ITEMFAMILY::PET_ANIMAL_TICKET
:
2099 string nr
= (itemInfo
.PetNumber
> 0) ? toString(itemInfo
.PetNumber
) : "(slot)" + toString(item
->getIndexInDB());
2100 strFindReplace(itemText
, "%petnumber", nr
);
2105 strFindReplace(itemText
, "%no_rent", pIS
->IsItemNoRent
? CI18N::get("uihelpItemNoRent") : string(""));
2106 strFindReplace(itemText
, "%descnr", pIS
->IsItemNoRent
? CI18N::get("uihelpItemNoRentDesc") : string(""));
2112 INVENTORIES::TInventory inventory
= (INVENTORIES::TInventory
)item
->getInventoryIndex();
2113 sint32 slot
= item
->getIndexInDB();
2114 string debugText
= NLMISC::toString("inventory: %s\nslot: %d\n", INVENTORIES::toString(inventory
).c_str(), slot
);
2115 itemText
= debugText
+ itemText
;
2120 // ***************************************************************************
2121 static void setupEnchantedItem(CSheetHelpSetup
&setup
, string
&itemText
)
2123 // if don't find the tag in the text (eg: if not useful), no-op
2124 static const string
enchantTag("%enchantment");
2125 if( itemText
.find(enchantTag
) == string::npos
)
2128 // retrieve the current itemInfo
2129 CDBCtrlSheet
*ctrl
= setup
.SrcSheet
;
2130 CInterfaceGroup
*group
= setup
.HelpWindow
;
2133 const CClientItemInfo
&itemInfo
= getInventory().getItemInfo(getInventory().getItemSlotId(ctrl
) );
2134 IListSheetBase
*listBrick
= dynamic_cast<IListSheetBase
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK
));
2136 // if the item is enchanted
2137 if( !itemInfo
.Enchantment
.empty())
2139 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
2141 // fill the enchantement info
2143 const CItemSheet
*pIS
= ctrl
->asItemSheet();
2144 if(pIS
&& pIS
->Family
== ITEMFAMILY::CRYSTALLIZED_SPELL
)
2145 pPM
->buildPhraseDesc(enchantInfo
, itemInfo
.Enchantment
, 0, false, "uihelpPhraseCrystalSpellFormat");
2147 pPM
->buildPhraseDesc(enchantInfo
, itemInfo
.Enchantment
, 0, false, "uihelpPhraseEnchantmentFormat");
2150 strFindReplace(itemText
, enchantTag
, enchantInfo
);
2152 // if exist, setup text header
2154 setupListBrickHeader(setup
);
2157 fillSabrinaPhraseListBrick(itemInfo
.Enchantment
, listBrick
);
2161 // must hide the listBrick
2163 listBrick
->setActive(false);
2165 // hide the list brick header
2166 hideListBrickHeader(setup
);
2169 strFindReplace(itemText
, enchantTag
, string());
2174 // ***************************************************************************
2175 static void setupRawMaterialStats(CSheetHelpSetup
&setup
)
2177 // retrieve the current itemInfo
2178 CDBCtrlSheet
*ctrl
= setup
.SrcSheet
;
2179 CInterfaceGroup
*group
= setup
.HelpWindow
;
2183 // get the group for raw material stat
2184 CInterfaceGroup
*groupMp
= dynamic_cast<CInterfaceGroup
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_GROUP_MP_STAT
));
2188 // if the item is a Mp
2189 const CItemSheet
*pIS
= ctrl
->asItemSheet();
2190 if(pIS
&& pIS
->Family
== ITEMFAMILY::RAW_MATERIAL
)
2192 // If the MP can craft some item part
2193 if(pIS
->canBuildSomeItemPart())
2195 // activate the mp stat group
2196 groupMp
->setActive(true);
2198 // Initialize the itempart selection combo box
2199 CDBGroupComboBox
*pCB
= dynamic_cast<CDBGroupComboBox
*>(groupMp
->getElement(groupMp
->getId()+":item_part_choice" ));
2203 for(uint i
=0;i
<RM_FABER_TYPE::NUM_FABER_TYPE
;i
++)
2205 RM_FABER_TYPE::TRMFType faberType
= RM_FABER_TYPE::TRMFType(i
);
2207 if(pIS
->canBuildItemPart(faberType
))
2209 pCB
->addText(RM_FABER_TYPE::toLocalString(faberType
));
2213 // force reset, but try to keep the precedent selection
2214 // (useful to test same item-part from different MPs)
2215 sint32 precSel
= pCB
->getSelection();
2216 pCB
->setSelection(1);
2217 pCB
->setSelection(0);
2218 if(precSel
>=0 && precSel
<(sint32
)pCB
->getNumTexts())
2220 pCB
->setSelection(precSel
);
2227 groupMp
->setActive(false);
2233 groupMp
->setActive(false);
2237 // ***************************************************************************
2238 void resetSheetHelp(CSheetHelpSetup
&setup
)
2240 CInterfaceGroup
*group
= setup
.HelpWindow
;
2244 // Hide the list of items by default
2245 IListSheetBase
*listItem
= dynamic_cast<IListSheetBase
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_LIST_ITEM
));
2248 listItem
->setActive(false);
2251 // Hide the item preview by default
2252 CInterfaceElement
*elt
= group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_ITEM_PREVIEW
);
2255 elt
->setActive(false);
2258 // Hide the list of brick by default
2259 IListSheetBase
*listBrick
= dynamic_cast<IListSheetBase
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK
));
2262 listBrick
->setActive(false);
2264 // Hide the mpstats by default
2265 CInterfaceGroup
*groupMp
= dynamic_cast<CInterfaceGroup
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_GROUP_MP_STAT
));
2267 groupMp
->setActive(false);
2268 // Hide the list of brick requirement by default
2269 listBrick
= dynamic_cast<IListSheetBase
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK_REQUIREMENT
));
2272 listBrick
->setActive(false);
2274 // Hide the listBrick header by default
2275 CViewText
*view
= dynamic_cast<CViewText
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK_HEADER
));
2278 view
->setActive(false);
2281 CInterfaceGroup
*groupCosmetic
= dynamic_cast<CInterfaceGroup
*>(group
->getElement(group
->getId()+setup
.PrefixForExtra
+INFO_GROUP_CHAR_3D
));
2283 groupCosmetic
->setActive(false);
2287 // ***************************************************************************
2288 static void setupItemHelp(CSheetHelpSetup
&setup
)
2290 if (!setup
.HelpWindow
) return;
2292 // get the calling item
2293 if (!setup
.SrcSheet
|| setup
.SrcSheet
->getType()!=CCtrlSheetInfo::SheetType_Item
)
2295 nlwarning("<CHandlerOpenItemHelp::execute> no caller sheet found");
2299 // If the sheet is 0, don't open!
2300 if(setup
.SrcSheet
->getSheetId()==0)
2305 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
2306 setup
.DestSheet
->setActive(true);
2309 // NB: for raw materials only, must do each once only, must not do it at refresh, cause combo reseted
2310 setupRawMaterialStats(setup
);
2312 // update the item Help
2313 refreshItemHelp(setup
);
2317 // ***************************************************************************
2318 void setupCosmetic(CSheetHelpSetup
&setup
, CItemSheet
*pIS
)
2321 if(pIS
->Family
!=ITEMFAMILY::COSMETIC
)
2324 EGSPD::CPeople::TPeople people
= ITEM_ORIGIN::itemOriginStringToPeopleEnum( ITEM_ORIGIN::enumToString( pIS
->ItemOrigin
) );
2325 if ( !( UserEntity
->getGender() != pIS
->Cosmetic
.Gender
|| UserEntity
->people() != people
) )
2327 CInterfaceGroup
*groupCosmetic
= dynamic_cast<CInterfaceGroup
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_GROUP_CHAR_3D
));
2329 groupCosmetic
->setActive(true);
2330 // display the character head in the help window
2331 CCharacterSummary cs
;
2332 SCharacter3DSetup::setupCharacterSummaryFromSERVERDB( cs
);
2333 // we dont want to display helmets
2334 cs
.VisualPropA
.PropertySubData
.HatModel
= SCharacter3DSetup::getDB ( "SERVER:USER:HAIR_TYPE" );
2335 cs
.VisualPropA
.PropertySubData
.HatColor
= SCharacter3DSetup::getDB ("SERVER:USER:HAIR_COLOR");
2336 if ( pIS
->ItemType
== ITEM_TYPE::HAIR_MALE
|| pIS
->ItemType
== ITEM_TYPE::HAIR_FEMALE
)
2337 cs
.VisualPropA
.PropertySubData
.HatModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::HEAD_SLOT
);
2338 else if ( pIS
->ItemType
== ITEM_TYPE::TATOO_MALE
|| pIS
->ItemType
== ITEM_TYPE::TATOO_FEMALE
)
2339 cs
.VisualPropC
.PropertySubData
.Tattoo
= pIS
->Cosmetic
.VPValue
;
2340 else if ( pIS
->ItemType
== ITEM_TYPE::HAIRCOLOR_MALE
|| pIS
->ItemType
== ITEM_TYPE::HAIRCOLOR_FEMALE
)
2341 cs
.VisualPropA
.PropertySubData
.HatColor
= pIS
->Cosmetic
.VPValue
;
2343 nlwarning("<setupItemHelp> Invalid cosmetic item type '%s'",ITEM_TYPE::toString( pIS
->ItemType
).c_str() );
2345 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D",cs
);
2349 // ***************************************************************************
2350 void setupItemPreview(CSheetHelpSetup
&setup
, CItemSheet
*pIS
)
2354 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2355 CCDBNodeBranch
*dbBranch
= NLGUI::CDBManager::getInstance()->getDbBranch( setup
.SrcSheet
->getSheet() );
2358 CInterfaceElement
*elt
= setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_ITEM_PREVIEW
);
2362 CInterfaceGroup
*ig
= dynamic_cast<CInterfaceGroup
*>(elt
);
2369 static sint32 helpWidth
= setup
.HelpWindow
->getW();
2370 bool scene_inactive
= ! NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:SHOW_3D_ITEM_PREVIEW")->getValueBool();
2371 if (scene_inactive
||
2372 (pIS
->Family
!= ITEMFAMILY::ARMOR
&&
2373 pIS
->Family
!= ITEMFAMILY::MELEE_WEAPON
&&
2374 pIS
->Family
!= ITEMFAMILY::RANGE_WEAPON
&&
2375 pIS
->Family
!= ITEMFAMILY::SHIELD
))
2377 setup
.HelpWindow
->setW(helpWidth
);
2378 ig
->setActive(false);
2383 setup
.HelpWindow
->setW(helpWidth
+ ITEM_PREVIEW_WIDTH
);
2384 ig
->setActive(true);
2387 CInterface3DScene
*sceneI
= dynamic_cast<CInterface3DScene
*>(ig
->getGroup("scene_item_preview"));
2390 nlwarning("Can't retrieve character 3d view, or bad type");
2391 ig
->setActive(false);
2395 CInterface3DCharacter
*char3DI
= NULL
;
2396 if (sceneI
->getCharacter3DCount() != 0)
2397 char3DI
= sceneI
->getCharacter3D(0);
2399 if (char3DI
== NULL
)
2401 nlwarning("Can't retrieve char 3D Interface");
2402 ig
->setActive(false);
2406 CInterface3DCamera
*camera
= sceneI
->getCamera(0);
2409 nlwarning("Can't retrieve camera");
2410 ig
->setActive(false);
2415 SCharacter3DSetup c3Ds
;
2417 CCharacterSummary cs
;
2418 SCharacter3DSetup::setupCharacterSummaryFromSERVERDB( cs
);
2420 float camHeight
= -0.85f
;
2422 if (pIS
->Family
== ITEMFAMILY::ARMOR
)
2424 if (pIS
->ItemType
== ITEM_TYPE::LIGHT_BOOTS
|| pIS
->ItemType
== ITEM_TYPE::MEDIUM_BOOTS
|| pIS
->ItemType
== ITEM_TYPE::HEAVY_BOOTS
)
2426 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2427 cs
.VisualPropB
.PropertySubData
.FeetModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::FEET_SLOT
);
2428 cs
.VisualPropB
.PropertySubData
.FeetColor
= color
->getValue32();
2429 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2432 else if (pIS
->ItemType
== ITEM_TYPE::LIGHT_GLOVES
|| pIS
->ItemType
== ITEM_TYPE::MEDIUM_GLOVES
|| pIS
->ItemType
== ITEM_TYPE::HEAVY_GLOVES
)
2434 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2435 cs
.VisualPropB
.PropertySubData
.HandsModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::HANDS_SLOT
);
2436 cs
.VisualPropB
.PropertySubData
.HandsColor
= color
->getValue32();
2437 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2438 //cs.VisualPropB.PropertySubData.HandsColor = pIS->Color;
2440 else if (pIS
->ItemType
== ITEM_TYPE::LIGHT_SLEEVES
|| pIS
->ItemType
== ITEM_TYPE::MEDIUM_SLEEVES
|| pIS
->ItemType
== ITEM_TYPE::HEAVY_SLEEVES
)
2442 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2443 cs
.VisualPropA
.PropertySubData
.ArmModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::ARMS_SLOT
);
2444 cs
.VisualPropA
.PropertySubData
.ArmColor
= color
->getValue32();
2445 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2446 //cs.VisualPropA.PropertySubData.ArmColor = pIS->Color;
2449 else if (pIS
->ItemType
== ITEM_TYPE::LIGHT_PANTS
|| pIS
->ItemType
== ITEM_TYPE::MEDIUM_PANTS
|| pIS
->ItemType
== ITEM_TYPE::HEAVY_PANTS
)
2451 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2452 cs
.VisualPropA
.PropertySubData
.TrouserModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::LEGS_SLOT
);
2453 cs
.VisualPropA
.PropertySubData
.TrouserColor
= color
->getValue32();
2454 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2457 else if (pIS
->ItemType
== ITEM_TYPE::LIGHT_VEST
|| pIS
->ItemType
== ITEM_TYPE::MEDIUM_VEST
|| pIS
->ItemType
== ITEM_TYPE::HEAVY_VEST
)
2459 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2460 cs
.VisualPropA
.PropertySubData
.JacketModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::CHEST_SLOT
);
2461 cs
.VisualPropA
.PropertySubData
.JacketColor
= color
->getValue32();
2462 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2465 else if (pIS
->ItemType
== ITEM_TYPE::HEAVY_HELMET
)
2467 CCDBNodeLeaf
*color
= dbBranch
->getLeaf( setup
.SrcSheet
->getSheet()+":USER_COLOR", false );
2468 cs
.VisualPropA
.PropertySubData
.HatModel
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::HEAD_SLOT
);
2469 cs
.VisualPropA
.PropertySubData
.HatColor
= color
->getValue32();
2470 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2474 else if (pIS
->Family
== ITEMFAMILY::SHIELD
)
2476 cs
.VisualPropA
.PropertySubData
.WeaponLeftHand
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::LEFT_HAND_SLOT
);
2477 if (cs
.VisualPropA
.PropertySubData
.WeaponRightHand
!= 0)
2479 CItemSheet
*pES
= SheetMngr
.getItem(SLOTTYPE::RIGHT_HAND_SLOT
, cs
.VisualPropA
.PropertySubData
.WeaponRightHand
);
2480 if (pES
->ItemType
== ITEM_TYPE::TWO_HAND_AXE
|| pES
->ItemType
== ITEM_TYPE::TWO_HAND_MACE
|| pES
->ItemType
== ITEM_TYPE::TWO_HAND_SWORD
||
2481 pES
->ItemType
== ITEM_TYPE::MAGICIAN_STAFF
|| pES
->ItemType
== ITEM_TYPE::AUTOLAUCH
|| pES
->ItemType
== ITEM_TYPE::LAUNCHER
|| pES
->ItemType
== ITEM_TYPE::RIFLE
)
2482 cs
.VisualPropA
.PropertySubData
.WeaponRightHand
= 0;
2484 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2487 else if (pIS
->Family
== ITEMFAMILY::MELEE_WEAPON
|| pIS
->Family
== ITEMFAMILY::RANGE_WEAPON
)
2489 cs
.VisualPropA
.PropertySubData
.WeaponRightHand
= CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup
.SrcSheet
->getSheetId()), SLOTTYPE::RIGHT_HAND_SLOT
);
2490 cs
.VisualPropA
.PropertySubData
.WeaponLeftHand
= 0;
2491 SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs
);
2494 nlwarning("<setupItemPreview> Invalid armour or weapon item type '%s'", ITEM_TYPE::toString( pIS
->ItemType
).c_str() );
2499 camera
->setTgtZ(camHeight
);
2500 char3DI
->setAnim(CAnimationStateSheet::Idle
);
2503 // ***************************************************************************
2504 void refreshItemHelp(CSheetHelpSetup
&setup
)
2506 // Setup creator name view
2507 setupCreatorName(setup
);
2509 // **** setup the item Text info
2511 CEntitySheet
*pES
= SheetMngr
.get ( CSheetId(setup
.SrcSheet
->getSheetId()) );
2512 if ((pES
!= NULL
) && (pES
->type() == CEntitySheet::ITEM
))
2514 CItemSheet
*pIS
= (CItemSheet
*)pES
;
2517 string title
= setup
.SrcSheet
->getItemActualName();
2518 setupHelpTitle(setup
.HelpWindow
, title
);
2519 getItemText (setup
.SrcSheet
, itemText
, pIS
);
2521 // ---- Enchanted items only
2522 setupEnchantedItem(setup
, itemText
);
2524 // ---- Cosmetic only
2525 setupCosmetic (setup
, pIS
);
2527 // ---- item preview
2528 setupItemPreview(setup
, pIS
);
2531 // if this is a R2 plot item, Add comment and description
2533 // BORIS : 06/09/2006 : removed because seams to build a double 'description' in the item info windows
2534 // const CItemSheet *pIS= setup.SrcSheet->asItemSheet();
2537 // if (pIS->Family == ITEMFAMILY::SCROLL_R2)
2539 // const R2::TMissionItem *mi = R2::getEditor().getPlotItemInfos((uint32) setup.SrcSheet->getSheetId());
2542 // itemText += CI18N::get("uiRingPlotItemDesc");
2543 // itemText += mi->Description.empty() ? CI18N::get("uiRingPlotItemEmpty")
2544 // : mi->Description;
2545 // //itemText += "\n@{6F6F}" + CI18N::get("uiRingPlotItemComment") + "\n";
2547 // itemText += mi->Comment.empty() ? CI18N::get("uiRingPlotItemEmpty")
2548 // : ("\n" + mi->Comment);
2555 // **** setup the text
2556 setHelpText(setup
, itemText
);
2560 // ***************************************************************************
2561 static void setupPactHelp(CSheetHelpSetup
&setup
)
2563 if (!setup
.HelpWindow
) return;
2565 // get the calling item
2566 if (!setup
.SrcSheet
)
2568 nlwarning("<CHandlerOpenBrickHelp::execute> no caller sheet found.");
2572 // If the sheet is 0, don't open!
2573 if(setup
.SrcSheet
->getSheetId()==0)
2576 const CPactSheet
*pact
= setup
.SrcSheet
->asPactSheet();
2579 nlwarning("<CHandlerOpenBrickHelp::execute> can't get pact.");
2583 // Level of the pact is in the quality.
2584 sint32 pactLevel
= setup
.SrcSheet
->getQuality();
2586 if (pactLevel
< 0 || pactLevel
>= (sint32
) pact
->PactLose
.size())
2588 nlwarning("<CHandlerOpenBrickHelp::execute> bad level for pact.");
2594 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
2595 setup
.DestSheet
->setActive(true);
2599 const CPactSheet::SPact
&pactLose
= pact
->PactLose
[pactLevel
];
2600 // **** setup the brick Text info
2603 // TODO Localisation
2604 setupHelpTitle(setup
.HelpWindow
, pactLose
.Name
);
2606 pactText
= CI18N::get("uihelpPactFormat");
2607 strFindReplace(pactText
, "%lvl", toString(pactLevel
));
2608 strFindReplace(pactText
, "%hp", toString(pactLose
.LoseHitPointsLevel
));
2609 strFindReplace(pactText
, "%sta", toString(pactLose
.LoseStaminaLevel
));
2610 strFindReplace(pactText
, "%sap", toString(pactLose
.LoseSapLevel
));
2611 strFindReplace(pactText
, "%skill", toString(pactLose
.LoseSkillsLevel
));
2613 // **** setup the text
2614 setHelpText(setup
, pactText
);
2618 // ***************************************************************************
2619 static void setupMissionHelp(CSheetHelpSetup
&setup
)
2621 // get the calling item
2622 if (!setup
.SrcSheet
)
2624 nlwarning("<setupMissionHelp> no caller sheet found.");
2629 // CDBCtrlSheet *ctrlMission= dynamic_cast<CDBCtrlSheet*>(setup.HelpWindow->getCtrl("ctrl_slot"));
2632 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
2633 setup
.DestSheet
->setActive(true);
2636 // get detail text id from db
2637 if (!setup
.SrcSheet
->getRootBranch()) return;
2638 CCDBNodeLeaf
*detailTextLeaf
= dynamic_cast<CCDBNodeLeaf
*>(setup
.SrcSheet
->getRootBranch()->getNode(ICDBNode::CTextId("DETAIL_TEXT")));
2639 if (!detailTextLeaf
) return;
2641 // Change the title according to Mission Client Type
2642 MISSION_DESC::TIconId iconId
= (MISSION_DESC::TIconId
)setup
.SrcSheet
->getSheetId();
2643 MISSION_DESC::TClientMissionType mType
= MISSION_DESC::getClientMissionType(iconId
);
2644 if(mType
==MISSION_DESC::Mission
)
2645 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpMission"));
2646 else if(mType
==MISSION_DESC::ZCRequirement
)
2647 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpZCRequirement"));
2648 else if(mType
==MISSION_DESC::BuildingRequirement
)
2649 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpBuildingRequirement"));
2650 else if(mType
==MISSION_DESC::ZCCharge
)
2651 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpZCCharge"));
2652 else if(mType
==MISSION_DESC::Building
)
2653 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpBuilding"));
2654 else if(mType
==MISSION_DESC::RMBuy
)
2655 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpRMBuy"));
2656 else if(mType
==MISSION_DESC::RMUpgrade
)
2657 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpRMUpgrade"));
2659 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpMission") );
2662 // **** setup the text id
2663 setHelpTextID(setup
, detailTextLeaf
->getValue32());
2665 CViewTextID
*viewTextTitleID
= dynamic_cast<CViewTextID
*>(setup
.HelpWindow
->getView("text_title_id"));
2666 if (viewTextTitleID
!= NULL
)
2668 CCDBNodeLeaf
*titleTextLeaf
= dynamic_cast<CCDBNodeLeaf
*>(setup
.SrcSheet
->getRootBranch()->getNode(ICDBNode::CTextId("TEXT")));
2669 if (titleTextLeaf
== NULL
) return;
2670 viewTextTitleID
->setTextId(titleTextLeaf
->getValue32());
2675 // ***************************************************************************
2676 void refreshMissionHelp(CSheetHelpSetup
&setup
, const CPrerequisitInfos
&infos
)
2678 static NLMISC::CRGBA
orange(250,150,0);
2679 static NLMISC::CRGBA
darkGreen(0,150,0);
2681 if (infos
.Prerequisits
.size() > 15)
2686 bool conditionValidated
= false;
2688 // NB : firts prerequisit MUST be an 'and'
2689 for (uint i
= 0 ; i
< infos
.Prerequisits
.size() ; )
2691 nlassert(infos
.Prerequisits
[i
].IsMandatory
);
2692 conditionValidated
= infos
.Prerequisits
[i
].Validated
;
2694 // check 'or' conditions, if any or (or enclosing 'and') is validated then global block is matched
2696 for ( orIndexMax
= i
+1 ; orIndexMax
< infos
.Prerequisits
.size() ; ++orIndexMax
)
2698 if (infos
.Prerequisits
[orIndexMax
].IsMandatory
)
2701 if (infos
.Prerequisits
[orIndexMax
].Validated
)
2702 conditionValidated
= true;
2705 // fill text, choose color according to conditions and block
2706 for (uint j
= i
; j
< orIndexMax
; ++j
)
2708 const string text
= setup
.HelpWindow
->getId() + ":content:scroll_text_id:text_list:" + NLMISC::toString("text_%u",j
+1);
2709 CViewText
*viewText
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getElement(text
));
2712 viewText
->setActive(true);
2713 if (infos
.Prerequisits
[j
].IsMandatory
)
2714 viewText
->setHardText("uiMissionAnd");
2716 viewText
->setHardText("uiMissionOr");
2719 const string textId
= setup
.HelpWindow
->getId() + ":content:scroll_text_id:text_list:" + NLMISC::toString("text_id_prereq_%u",j
+1);
2721 CViewTextID
*viewTextID
= dynamic_cast<CViewTextID
*>(setup
.HelpWindow
->getElement(textId
));
2724 // not validated : change color to red
2725 if (!infos
.Prerequisits
[j
].Validated
)
2727 if (!conditionValidated
)
2728 viewTextID
->setColor(orange
);
2730 viewTextID
->setColor(CRGBA::White
);
2733 viewTextID
->setColor(darkGreen
);
2735 viewTextID
->setActive(true);
2736 viewTextID
->setTextId(infos
.Prerequisits
[j
].Description
);
2740 // go to next 'and' statement (or end)
2744 // inactivate other lines
2745 for (uint i
= (uint
)infos
.Prerequisits
.size(); i
< 15 ; ++i
)
2747 const string text
= setup
.HelpWindow
->getId() + ":content:scroll_text_id:text_list:" + NLMISC::toString("text_%u",i
+1);
2748 CViewText
*viewText
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getElement(text
));
2750 viewText
->setActive(false);
2752 const string textId
= setup
.HelpWindow
->getId() + ":content:scroll_text_id:text_list:" + NLMISC::toString("text_id_prereq_%u",i
+1);
2753 CViewTextID
*viewTextID
= dynamic_cast<CViewTextID
*>(setup
.HelpWindow
->getElement(textId
));
2755 viewTextID
->setActive(false);
2758 if (!setup
.ScrollTextGroup
.empty())
2760 CInterfaceGroup
*viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextGroup
);
2761 if (viewTextGroup
) viewTextGroup
->setActive(false);
2763 CInterfaceGroup
*viewTextGroup
= setup
.HelpWindow
->getGroup(setup
.ScrollTextIdGroup
);
2764 if (viewTextGroup
) viewTextGroup
->setActive(true);
2767 // ***************************************************************************
2768 class CPlayerShardNameRemover
: public IOnReceiveTextId
2770 virtual void onReceiveTextId(std::string
&str
)
2772 str
= CEntityCL::removeShardFromName(str
);
2775 static CPlayerShardNameRemover PlayerShardNameRemover
;
2777 // ***************************************************************************
2778 void setupCreatorName(CSheetHelpSetup
&setup
)
2780 if (!setup
.HelpWindow
) return;
2781 CViewTextID
*vtid
= dynamic_cast<CViewTextID
*>(setup
.HelpWindow
->getView(setup
.CreatorViewTextID
));
2782 CViewText
*vthd
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getView("creator_header"));
2788 const CItemSheet
*pIS
= dynamic_cast<const CItemSheet
*>(SheetMngr
.get(CSheetId(setup
.SrcSheet
->getSheetId())));
2789 bIsRM
= (pIS
&& pIS
->Family
== ITEMFAMILY::RAW_MATERIAL
);
2792 // if a RM or not an item, disable the view
2793 if(!setup
.SrcSheet
|| bIsRM
|| setup
.SrcSheet
->getType()!=CCtrlSheetInfo::SheetType_Item
)
2795 // important else a brick could display a creator name....
2796 vtid
->setActive(false);
2798 vthd
->setActive(false);
2802 // get the CreatorTextID
2803 uint32 itemSlotId
= getInventory().getItemSlotId(setup
.SrcSheet
);
2804 uint32 creatorTextId
= getInventory().getItemInfo(itemSlotId
).CreatorName
;
2806 vtid
->setActive(true);
2807 vtid
->setTextId(creatorTextId
);
2808 vtid
->setOnReceiveTextId(&PlayerShardNameRemover
);
2810 vthd
->setActive(creatorTextId
!=0);
2815 // ***************************************************************************
2816 // ***************************************************************************
2817 // Outpost Building Help
2818 // ***************************************************************************
2819 // ***************************************************************************
2822 // ***************************************************************************
2823 void fillOutpostBuildingListItem(const std::vector
<NLMISC::CSheetId
> &mps
, IListSheetBase
*listItem
, uint32 qualityLevel
)
2825 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2829 listItem
->setActive(true);
2830 string branchBase
= listItem
->getDbBranchName();
2833 for(i
=0;i
<mps
.size();i
++)
2835 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:SHEET", branchBase
.c_str(), i
));
2837 node
->setValue32(mps
[i
].asInt());
2838 node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:QUALITY", branchBase
.c_str(), i
), false);
2840 node
->setValue32(qualityLevel
);
2841 node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:PREREQUISIT_VALID", branchBase
.c_str(), i
), false);
2843 node
->setValue32(1);
2845 // Reset other to 0.
2848 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:SHEET", branchBase
.c_str(), i
), false);
2850 node
->setValue32(0);
2857 // ***************************************************************************
2858 void setupOutpostBuildingHelp(CSheetHelpSetup
&setup
)
2860 // get the calling item
2861 if (!setup
.SrcSheet
)
2863 nlwarning("<setupOutpostBuildingHelp> no caller sheet found.");
2870 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
2871 setup
.DestSheet
->setActive(true);
2874 const COutpostBuildingSheet
*pOBS
= setup
.SrcSheet
->asOutpostBuildingSheet();
2877 nlwarning("<setupOutpostBuildingHelp> can't get outpost building sheet.");
2881 setupHelpTitle(setup
.HelpWindow
, CI18N::get("uihelpOutpostBuilding"));
2885 sOBText
= CI18N::get("uihelpOBFormat_"+COutpostBuildingSheet::toString(pOBS
->OBType
));
2889 timeText
= toString(pOBS
->CostTime
/60) + CI18N::get("uiBotChatTimeMinute");
2890 if ((pOBS
->CostTime
% 60) != 0)
2891 timeText
+= toString(pOBS
->CostTime
%60) + CI18N::get("uiBotChatTimeSecond");
2893 strFindReplace(sOBText
, "%costtime", timeText
);
2896 strFindReplace(sOBText
, "%costdapper", toString(pOBS
->CostDapper
));
2898 // Set name of the building
2899 strFindReplace(sOBText
, "%name", STRING_MANAGER::CStringManagerClient::getOutpostBuildingLocalizedName(pOBS
->Id
));
2901 // For driller, set lvl
2902 strFindReplace(sOBText
, "%lvl", toString(pOBS
->MPLevelOfHighestExtractRate
));
2904 // **** setup the text
2905 setHelpText(setup
, sOBText
);
2907 // **** raw materials stats for driller to buy
2908 if(pOBS
->OBType
==COutpostBuildingSheet::OB_Driller
)
2910 // Get the list of bricks container
2911 IListSheetBase
*listItem
= dynamic_cast<IListSheetBase
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_LIST_ITEM
));
2914 fillOutpostBuildingListItem(pOBS
->Mps
, listItem
, pOBS
->MPLevelOfHighestExtractRate
);
2918 // ***************************************************************************
2919 // ***************************************************************************
2920 // SBrick / Phrase help
2921 // ***************************************************************************
2922 // ***************************************************************************
2925 // ***************************************************************************
2926 static bool getAuraDisabledState(CDBCtrlSheet
*cs
)
2928 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2933 // Get the DISABLED DBprop
2934 string db
= cs
->getSheet() + ":DISABLED";
2935 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(db
, false);
2936 return node
&& node
->getValue32()!=0;
2939 // ***************************************************************************
2940 static sint
getBonusMalusSpecialTT(CDBCtrlSheet
*cs
)
2942 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
2947 // Get the SPECIAL_TOOLTIP DBprop
2948 string db
= cs
->getSheet() + ":SPECIAL_TOOLTIP";
2949 return NLGUI::CDBManager::getInstance()->getDbValue32 (db
);
2953 // ***************************************************************************
2954 void getSabrinaBrickText(CSBrickSheet
*pBR
, string
&brickText
)
2959 // *** get the formated text according to Brick type.
2960 if( pBR
->isFaber() && pBR
->isMandatory() )
2962 brickText
= CI18N::get("uihelpBrickFaberFormat");
2966 brickText
= CI18N::get("uihelpBrickFormat");
2971 strFindReplace(brickText
, "%lvl", toString(pBR
->Level
));
2972 // Kill the whole text between %ks, if the skill is unknown
2973 const string
killSkill("%ks");
2974 if( pBR
->getSkill()==SKILLS::unknown
)
2976 string::size_type pos0
= brickText
.find(killSkill
);
2977 if(pos0
!= string::npos
)
2979 string::size_type pos1
= brickText
.find(killSkill
, pos0
+ killSkill
.size() );
2980 if(pos1
!= string::npos
)
2981 brickText
.replace(pos0
, pos1
+killSkill
.size()-pos0
, string() );
2987 while(strFindReplace(brickText
, "%ks", ""));
2989 // Skill, or array of skill for combat
2990 if(pBR
->UsedSkills
.size()==1)
2991 strFindReplace(brickText
, "%skill", CStringManagerClient::getSkillLocalizedName(pBR
->getSkill()));
2994 string fullSkillText
;
2996 for(uint i
=0;i
<pBR
->UsedSkills
.size();i
++)
2998 SKILLS::ESkills skill
= pBR
->UsedSkills
[i
];
2999 if(skill
!=SKILLS::unknown
)
3002 fullSkillText
+= CI18N::get("uihelpBrickCombatSkillSeparator");
3004 fullSkillText
+= CStringManagerClient::getSkillLocalizedName(skill
);
3008 strFindReplace(brickText
, "%skill", fullSkillText
);
3013 strFindReplace(brickText
, "%cost", toString(pBR
->SabrinaCost
));
3014 // Header Cost: cost or credit
3015 if(pBR
->SabrinaCost
>=0)
3016 strFindReplace(brickText
, "%hcost", CI18N::get("uihelpSabrinaCost") );
3018 strFindReplace(brickText
, "%hcost", CI18N::get("uihelpSabrinaCredit") );
3021 // Kill the whole text between %krc, if the relative cost is 0
3022 if(pBR
->SabrinaRelativeCost
==0.f
)
3024 const string
killRC("%krc");
3025 string::size_type pos0
= brickText
.find(killRC
);
3026 if(pos0
!= string::npos
)
3028 string::size_type pos1
= brickText
.find(killRC
, pos0
+ killRC
.size() );
3029 if(pos1
!= string::npos
)
3030 brickText
.replace(pos0
, pos1
+killRC
.size()-pos0
, string() );
3036 while(strFindReplace(brickText
, "%krc", ""));
3039 strFindReplace(brickText
, "%relative_cost", toPercentageText(pBR
->SabrinaRelativeCost
)+string("%"));
3040 // Header Cost: cost or credit
3041 if(pBR
->SabrinaRelativeCost
>=0.f
)
3042 strFindReplace(brickText
, "%hrel_cost", CI18N::get("uihelpSabrinaRelCost") );
3044 strFindReplace(brickText
, "%hrel_cost", CI18N::get("uihelpSabrinaRelCredit") );
3048 strFindReplace(brickText
, "%desc", CStringManagerClient::getSBrickLocalizedDescription(pBR
->Id
) );
3051 if( pBR
->isFaber() && pBR
->isMandatory() )
3053 // Display the ToolType required.
3054 strFindReplace(brickText
, "%tool", CI18N::get("tool"+TOOL_TYPE::toString(pBR
->FaberPlan
.ToolType
)));
3056 // --- Display MP itempart information
3057 if(pBR
->FaberPlan
.ItemPartMps
.empty())
3059 strFindReplace(brickText
, "%mpinfo", CI18N::get("uihelpMpNone"));
3064 for(uint i
=0;i
<pBR
->FaberPlan
.ItemPartMps
.size();i
++)
3066 CSBrickSheet::CFaberPlan::CItemPartMP
&mpSlot
= pBR
->FaberPlan
.ItemPartMps
[i
];
3068 // Display the part this slot build.
3070 mpInfo
+= RM_FABER_TYPE::toLocalString(mpSlot
.FaberTypeFilter
);
3073 // replace in brickText
3074 strFindReplace(brickText
, "%mpinfo", mpInfo
);
3077 // --- Display MP formula information
3078 if(pBR
->FaberPlan
.FormulaMps
.empty())
3080 strFindReplace(brickText
, "%mpformula", CI18N::get("uihelpMpNone"));
3085 for(uint i
=0;i
<pBR
->FaberPlan
.FormulaMps
.size();i
++)
3087 CSBrickSheet::CFaberPlan::CFormulaMP
&mpSlot
= pBR
->FaberPlan
.FormulaMps
[i
];
3089 // Display the required item
3091 mpInfo
+= STRING_MANAGER::CStringManagerClient::getItemLocalizedName(mpSlot
.ItemRequired
);
3094 // replace in brickText
3095 strFindReplace(brickText
, "%mpformula", mpInfo
);
3100 string magicResistStr
;
3101 // Has Some Magic Resistance setuped?
3102 if( pBR
->isMagic() && pBR
->MagicResistType
!=RESISTANCE_TYPE::None
)
3104 magicResistStr
= CI18N::get("uihelpBrickMagicResist");
3105 strFindReplace(magicResistStr
, "%t", CI18N::get("rs"+RESISTANCE_TYPE::toString(pBR
->MagicResistType
) ));
3107 strFindReplace(brickText
, "%magicresist", magicResistStr
);
3111 // ***************************************************************************
3113 * Used both by setupSabrinaPhraseHelp() and setupEnchantedItem()
3115 void fillSabrinaPhraseListBrick(const CSPhraseCom
&phrase
, IListSheetBase
*listBrick
)
3117 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3118 CSBrickManager
*pBM
= CSBrickManager::getInstance();
3122 listBrick
->setActive(true);
3123 string branchBase
= listBrick
->getDbBranchName();
3124 // setup phrase bricks
3126 for(i
=0;i
<phrase
.Bricks
.size();i
++)
3128 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:SHEET", branchBase
.c_str(), i
));
3130 node
->setValue32(phrase
.Bricks
[i
].asInt());
3132 // For requirements bricks, update the LOCKED state
3133 node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:LOCKED", branchBase
.c_str(), i
));
3136 if(pBM
->isBrickKnown(phrase
.Bricks
[i
]))
3137 node
->setValue32(0);
3140 node
->setValue32(2);
3143 // Reset other to 0.
3146 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("%s:%d:SHEET", branchBase
.c_str(), i
), false);
3148 node
->setValue32(0);
3155 void hideListBrickHeader(CSheetHelpSetup
&setup
)
3157 // CInterfaceManager *pIM= CInterfaceManager::getInstance();
3159 // get the header text
3160 CViewText
*view
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK_HEADER
));
3163 view
->setActive(false);
3167 void setupListBrickHeader(CSheetHelpSetup
&setup
)
3169 // get the header text
3170 CViewText
*view
= dynamic_cast<CViewText
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK_HEADER
));
3173 view
->setActive(true);
3174 view
->setTextFormatTaged(CI18N::get("uihelpPhraseHeaderBricks"));
3179 // ***************************************************************************
3180 /* phraseSheetId: not null if comes from a .sphrase Sheet, used to show progression info
3182 void setupSabrinaPhraseHelp(CSheetHelpSetup
&setup
, const CSPhraseCom
&phrase
, uint32 phraseSheetId
)
3184 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
3186 if(!setup
.SrcSheet
|| phrase
.empty())
3189 if(!setup
.HelpWindow
)
3195 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
3196 setup
.DestSheet
->setActive(true);
3199 // **** setup the phrase Text info
3200 setupHelpTitle(setup
.HelpWindow
, phrase
.Name
.toUtf8());
3202 // get the phraseText
3204 // if required, add the .sphrase requirements.
3205 // NB: don't add if from bot chat validation (useless cause already filtered by server)
3206 pPM
->buildPhraseDesc(phraseText
, phrase
, phraseSheetId
, !setup
.FromBotChat
);
3209 // **** If interesting to do it, setup the brick list
3210 if( pPM
->allowListBrickInHelp(phrase
) )
3212 // Get the list of bricks container
3213 IListSheetBase
*listBrick
= dynamic_cast<IListSheetBase
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK
));
3215 // if exist, setup text header
3217 setupListBrickHeader(setup
);
3220 fillSabrinaPhraseListBrick(phrase
, listBrick
);
3224 // **** For .sphrase only, setup the requirement bricks
3225 if(phraseSheetId
!=0)
3227 IListSheetBase
*listBrick
= dynamic_cast<IListSheetBase
*>(setup
.HelpWindow
->getElement(setup
.HelpWindow
->getId()+setup
.PrefixForExtra
+INFO_LIST_BRICK_REQUIREMENT
));
3230 CSPhraseCom dummyPhrase
;
3231 pPM
->buildPhraseBrickRequirement(phraseSheetId
, dummyPhrase
.Bricks
);
3232 if(!dummyPhrase
.Bricks
.empty())
3234 phraseText
+= CI18N::get("uihelpPhraseBrickRequirement");
3235 fillSabrinaPhraseListBrick(dummyPhrase
, listBrick
);
3241 // **** setup the final text
3242 setHelpText(setup
, phraseText
);
3246 // ***************************************************************************
3247 static void setupSabrinaBrickHelp(CSheetHelpSetup
&setup
, bool auraDisabled
)
3249 if (!setup
.HelpWindow
) return;
3251 // get the calling item
3252 if (!setup
.SrcSheet
|| !setup
.SrcSheet
->isSBrick() )
3254 nlwarning("<CHandlerOpenBrickHelp::execute> no caller sheet found");
3258 // If the sheet is 0, don't open!
3259 if(setup
.SrcSheet
->getSheetId()==0)
3265 setup
.SrcSheet
->copyAspect(setup
.DestSheet
);
3266 setup
.DestSheet
->setActive(true);
3270 // **** setup the brick Text info
3272 CSBrickManager
*pBM
= CSBrickManager::getInstance();
3273 CSBrickSheet
*pBR
= pBM
->getBrick(CSheetId(setup
.SrcSheet
->getSheetId()));
3276 const char *title
= CStringManagerClient::getSBrickLocalizedName(pBR
->Id
);
3277 setupHelpTitle(setup
.HelpWindow
, title
);
3280 getSabrinaBrickText(pBR
, brickText
);
3282 // Append special Aura Info
3285 brickText
+= CI18N::get("uihelpAuraDisabled");
3290 // **** setup the text
3291 setHelpText(setup
, brickText
);
3294 // ***************************************************************************
3295 void CSheetHelpSetup::setupDefaultIDs()
3298 ViewTextID
= "text_id";
3299 ScrollTextGroup
= "scroll_text";
3300 ScrollTextIdGroup
= "scroll_text_id";
3301 CreatorViewTextID
= "creator";
3302 PrefixForExtra
= ":content:scroll_text:text_list:";
3306 // ***************************************************************************
3307 void setupSheetHelp(CSheetHelpSetup
&setup
)
3309 if (!setup
.SrcSheet
) return;
3310 switch(setup
.SrcSheet
->getType())
3312 case CCtrlSheetInfo::SheetType_Skill
: setupSkillToTradeHelp(setup
); break;
3313 case CCtrlSheetInfo::SheetType_Item
: setupItemHelp(setup
); break;
3314 case CCtrlSheetInfo::SheetType_Pact
: setupPactHelp(setup
); break;
3315 case CCtrlSheetInfo::SheetType_Mission
: setupMissionHelp(setup
); break;
3316 case CCtrlSheetInfo::SheetType_SPhrase
:
3319 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
3320 uint32 phraseSheetId
= setup
.SrcSheet
->getSheetId();
3321 pPM
->buildPhraseFromSheet(phrase
, phraseSheetId
);
3322 setupSabrinaPhraseHelp(setup
, phrase
, phraseSheetId
);
3325 case CCtrlSheetInfo::SheetType_OutpostBuilding
: setupOutpostBuildingHelp(setup
); break;
3327 nlwarning("<CHandlerOpenHelpAuto> Bad item type.");
3333 // ***************************************************************************
3334 class CHandlerOpenPhraseIdHelp
: public IActionHandler
3337 virtual void execute (CCtrlBase
*pCaller
, const string
&Params
)
3339 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
3340 if (cs
!= NULL
&& cs
->getType()==CCtrlSheetInfo::SheetType_SPhraseId
)
3342 // Get the CSPhraseCom pointed.
3343 sint32 id
= cs
->getSPhraseId();
3346 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
3347 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
);
3349 CSheetHelpSetup setup
;
3350 setup
.setupDefaultIDs();
3351 setup
.HelpWindow
= group
;
3352 setup
.SrcSheet
= cs
;
3353 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getCtrl("ctrl_slot"));
3354 setupSabrinaPhraseHelp(setup
, pPM
->getPhrase(id
), 0);
3359 REGISTER_ACTION_HANDLER( CHandlerOpenPhraseIdHelp
, "open_phraseid_help");
3362 // ***************************************************************************
3363 class CHandlerOpenSBrickHelp
: public IActionHandler
3366 virtual void execute (CCtrlBase
*pCaller
, const string
&Params
)
3368 CSBrickManager
*pBM
= CSBrickManager::getInstance();
3369 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
3371 // No Info if bad control / no sheetid
3372 if(!cs
|| cs
->getSheetId()==0)
3374 CSheetId brickSheetId
= CSheetId(cs
->getSheetId());
3375 // No Info for the special "Remove Me" brick
3376 if(brickSheetId
== pBM
->getInterfaceRemoveBrick() )
3378 // No Info for special "XP catalyzer" or "PVP oupost" interface brick in bonus malus window
3379 string brickName
= brickSheetId
.toString();
3380 string xpCatBrickPrefix
= "big_xpcat_";
3381 string ringXpCatBrickPrefix
= "big_ring_xpcat_";
3382 string pvpOutpostBrickPrefix
= "big_outpost_pvp_";
3383 if(brickName
.compare(0, xpCatBrickPrefix
.size(), xpCatBrickPrefix
)==0)
3385 if(brickName
.compare(0, ringXpCatBrickPrefix
.size(), ringXpCatBrickPrefix
)==0)
3387 if(brickName
.compare(0, pvpOutpostBrickPrefix
.size(), pvpOutpostBrickPrefix
)==0)
3390 // Else, Ok open the window
3392 // get the forceKeep param (for Action info)
3393 sint forceKeepWindow
= -1;
3394 string forceKeepWindowStr
= getParam(Params
, "force_keep");
3395 if(!forceKeepWindowStr
.empty())
3396 fromString(forceKeepWindowStr
, forceKeepWindow
);
3397 // get the Aura Disabled param
3398 bool auraDisabled
= false;
3399 string auraDisabledStr
= getParam(Params
, "test_aura_disabled");
3400 bool tmpAuraDisabled
;
3401 fromString(auraDisabledStr
, tmpAuraDisabled
);
3403 auraDisabled
= getAuraDisabledState(cs
);
3406 CInterfaceGroup
*group
= CInterfaceHelp::activateNextWindow(cs
, forceKeepWindow
);
3408 CSheetHelpSetup setup
;
3409 setup
.setupDefaultIDs();
3410 setup
.HelpWindow
= group
;
3411 setup
.SrcSheet
= cs
;
3412 setup
.DestSheet
= dynamic_cast<CDBCtrlSheet
*>(group
->getCtrl("ctrl_slot"));
3413 setupSabrinaBrickHelp(setup
, auraDisabled
);
3417 REGISTER_ACTION_HANDLER( CHandlerOpenSBrickHelp
, "open_sbrick_help");
3421 // ***************************************************************************
3422 class CHandlerOnCloseHelp
: public IActionHandler
3425 virtual void execute (CCtrlBase
*pCaller
, const string
&Params
)
3427 // Remove the waiter for special ItemInfo
3429 fromString(Params
, index
);
3430 CInterfaceHelp::removeWaiterItemInfo(index
);
3431 CInterfaceHelp::removeWaiterMissionInfo(index
);
3433 // unpuhsed the "Keep" button.
3434 CInterfaceHelp::setKeepMode(index
, false);
3437 REGISTER_ACTION_HANDLER( CHandlerOnCloseHelp
, "on_close_help");
3440 // ***************************************************************************
3441 class CHandlerHelpKeep
: public IActionHandler
3444 virtual void execute (CCtrlBase
*pCaller
, const string
&Params
)
3448 fromString(Params
, index
);
3449 CInterfaceHelp::changeKeepMode(index
);
3452 REGISTER_ACTION_HANDLER( CHandlerHelpKeep
, "help_keep");
3455 // ***************************************************************************
3456 class CHandlerHelpResetPos
: public IActionHandler
3459 virtual void execute(CCtrlBase
*pCaller
, const string
&Params
)
3462 fromString(getParam(Params
, "y"), y
);
3463 // update WindowList if possible
3464 CInterfaceHelp::resetWindowPos(y
);
3467 REGISTER_ACTION_HANDLER( CHandlerHelpResetPos
, "help_reset_pos");
3471 //-----------------------------------------------
3472 // setConsoModSuccessTooltip
3473 //-----------------------------------------------
3474 void setConsoModSuccessTooltip( CDBCtrlSheet
*cs
)
3479 CInterfaceManager
* pIM
= CInterfaceManager::getInstance();
3481 CCDBNodeLeaf
* nodeSM
= NULL
;
3483 if( CSheetId(cs
->getSheetId()).toString() == "mod_melee_success.sbrick" )
3485 ustr
= CI18N::get("uittModMeleeSuccess");
3486 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:MELEE", false);
3489 if( CSheetId(cs
->getSheetId()).toString() == "mod_range_success.sbrick" )
3491 ustr
= CI18N::get("uittModRangeSuccess");
3492 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:RANGE", false);
3495 if( CSheetId(cs
->getSheetId()).toString() == "mod_craft_success.sbrick" )
3497 ustr
= CI18N::get("uittModCraftSuccess");
3498 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:CRAFT", false);
3501 if( CSheetId(cs
->getSheetId()).toString() == "mod_defense_success.sbrick" )
3503 ustr
= CI18N::get("uittModDefenseSuccess");
3504 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:DODGE", false);
3507 if( CSheetId(cs
->getSheetId()).toString() == "mod_dodge_success.sbrick" )
3509 ustr
= CI18N::get("uittModDodgeSuccess");
3510 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:DODGE", false);
3513 if( CSheetId(cs
->getSheetId()).toString() == "mod_parry_success.sbrick" )
3515 ustr
= CI18N::get("uittModParrySuccess");
3516 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:PARRY", false);
3519 if( CSheetId(cs
->getSheetId()).toString() == "mod_forage_success.sbrick" )
3521 ustr
= CI18N::get("uittModForageSuccess");
3522 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::common_ecosystem
)+":FORAGE", false);
3525 if( CSheetId(cs
->getSheetId()).toString() == "mod_desert_forage_success.sbrick" )
3527 ustr
= CI18N::get("uittModDesertForageSuccess");
3528 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::desert
)+":FORAGE", false);
3531 if( CSheetId(cs
->getSheetId()).toString() == "mod_forest_forage_success.sbrick" )
3533 ustr
= CI18N::get("uittModForestForageSuccess");
3534 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::forest
)+":FORAGE", false);
3537 if( CSheetId(cs
->getSheetId()).toString() == "mod_lacustre_forage_success.sbrick" )
3539 ustr
= CI18N::get("uittModLacustreForageSuccess");
3540 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::lacustre
)+":FORAGE", false);
3543 if( CSheetId(cs
->getSheetId()).toString() == "mod_jungle_forage_success.sbrick" )
3545 ustr
= CI18N::get("uittModJungleForageSuccess");
3546 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::jungle
)+":FORAGE", false);
3549 if( CSheetId(cs
->getSheetId()).toString() == "mod_primary_root_forage_success.sbrick" )
3551 ustr
= CI18N::get("uittModPrimaryRootForageSuccess");
3552 nodeSM
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:CHARACTER_INFO:SUCCESS_MODIFIER:ECO:"+toString((uint8
)ECOSYSTEM::primary_root
)+":FORAGE", false);
3557 if( nodeSM
->getValue32() < 0 )
3558 strFindReplace(ustr
, "%modifier", "@{E42F}-"+toString(nodeSM
->getValue32())+"@{FFFF}");
3560 strFindReplace(ustr
, "%modifier", "@{0F0F}"+toString(nodeSM
->getValue32())+"@{FFFF}");
3562 // replace the context help that is required.
3563 CWidgetManager::getInstance()->setContextHelpText(ustr
);
3568 // ***************************************************************************
3569 class CHandlerAuraModifierTooltip
: public IActionHandler
3572 virtual void execute(CCtrlBase
*pCaller
, const string
&Params
)
3574 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3575 CDBCtrlSheet
*cs
= dynamic_cast<CDBCtrlSheet
*>(pCaller
);
3579 // set value of consumable's tootltip
3580 setConsoModSuccessTooltip(cs
);
3582 // special tooltip? (pvp outpost and xp catalyzer)
3583 sint specialTTId
= getBonusMalusSpecialTT(cs
);
3584 if(specialTTId
==BONUS_MALUS::XpCatalyser
)
3585 CWidgetManager::getInstance()->setContextHelpText(CI18N::get("uittXpBonus"));
3586 else if(specialTTId
==BONUS_MALUS::OutpostPVPOn
)
3587 CWidgetManager::getInstance()->setContextHelpText(CI18N::get("uittPvpOutpostOn"));
3588 else if(specialTTId
==BONUS_MALUS::OutpostPVPOutOfZone
)
3589 CWidgetManager::getInstance()->setContextHelpText(CI18N::get("uittPvpOutpostOutOfZone"));
3590 else if(specialTTId
==BONUS_MALUS::OutpostPVPInRound
)
3591 CWidgetManager::getInstance()->setContextHelpText(CI18N::get("uittPvpOutpostInRound"));
3592 else if(specialTTId
==BONUS_MALUS::DeathPenalty
)
3594 CCDBNodeLeaf
* node
= NLGUI::CDBManager::getInstance()->getDbProp("SERVER:USER:DEATH_XP_MALUS", false);
3597 string txt
= CI18N::get("uittDeathPenalty");
3598 strFindReplace(txt
, "%dp", toString((100*node
->getValue16())/254));
3599 CWidgetManager::getInstance()->setContextHelpText(txt
);
3603 else if( getAuraDisabledState(cs
) )
3605 // get the normal string, and append a short info.
3607 cs
->getContextHelp(str
);
3609 str
+= CI18N::get("uittAuraDisabled");
3611 // and replace the context help that is required.
3612 CWidgetManager::getInstance()->setContextHelpText(str
);
3614 // else keep the default one
3617 REGISTER_ACTION_HANDLER( CHandlerAuraModifierTooltip
, "aura_modifier_tooltip");
3619 // ***************************************************************************
3620 class CHandlerUserPaToolTip
: public IActionHandler
3623 virtual void execute(CCtrlBase
*pCaller
, const string
&Params
)
3625 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3628 fromString(Params
, index
);
3629 --index
; // Param is 1-based so subtract 1
3630 if (index
>= MAX_INVENTORY_ANIMAL
)
3636 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d:NAME", index
));
3637 if (node
&& CStringManagerClient::instance()->getDynString(node
->getValue32(), txt
))
3639 CWidgetManager::getInstance()->setContextHelpText(CEntityCL::removeTitleFromName(txt
));
3643 REGISTER_ACTION_HANDLER( CHandlerUserPaToolTip
, "userpa_name_tooltip");
3645 // ***************************************************************************
3646 class CHandlerAnimalDeadPopupTooltip
: public IActionHandler
3649 virtual void execute(CCtrlBase
*pCaller
, const string
&Params
)
3651 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3652 // Find the mount's db leaf
3653 CCDBNodeBranch
*animalsNode
= safe_cast
<CCDBNodeBranch
*>(NLGUI::CDBManager::getInstance()->getDB()->getNode( ICDBNode::CTextId( "SERVER:PACK_ANIMAL" ), false ));
3654 BOMB_IF( ! animalsNode
, "! animalsNode", return; );
3655 sint32 minTimeRemaining
= -1;
3656 uint nbAnimals
= (uint
)animalsNode
->getNbNodes();
3657 for ( uint i
=0; i
!=nbAnimals
; ++i
)
3659 CCDBNodeLeaf
*statusNode
= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d", i
) + ":STATUS", false);
3660 if (statusNode
&& ANIMAL_STATUS::isDead((ANIMAL_STATUS::EAnimalStatus
)statusNode
->getValue32()) )
3662 ICDBNode
*beastNode
= animalsNode
->getNode( i
);
3663 // CCDBNodeLeaf *uidLeaf = safe_cast<CCDBNodeLeaf*>(beastNode->getNode( ICDBNode::CTextId( "UID" ) ));
3664 CCDBNodeLeaf
*despawnLeaf
= safe_cast
<CCDBNodeLeaf
*>(beastNode
->getNode( ICDBNode::CTextId( "DESPAWN" ) ));
3665 if( minTimeRemaining
== -1 )
3667 minTimeRemaining
= despawnLeaf
->getValue32();
3670 if( minTimeRemaining
> despawnLeaf
->getValue32() )
3672 minTimeRemaining
= despawnLeaf
->getValue32();
3678 BOMB_IF( minTimeRemaining
< 0, "at least one animal should be dead", return; );
3680 str
+= CI18N::get("uittAnimalDeadPopupToolTip");
3682 str
+= toString(minTimeRemaining
);
3684 // replace the context help that is required.
3685 CWidgetManager::getInstance()->setContextHelpText(str
);
3688 REGISTER_ACTION_HANDLER( CHandlerAnimalDeadPopupTooltip
, "animal_dead_popup_tooltip");
3692 // ***************************************************************************
3693 // ***************************************************************************
3694 // ***************************************************************************
3696 // ***************************************************************************
3697 // ***************************************************************************
3698 // ***************************************************************************
3700 #include "../motion/user_controls.h"
3701 #include "../entities.h"
3702 #include "people_interraction.h"
3703 #include "../net_manager.h"
3705 // ***************************************************************************
3706 class CAHMilkoKick
: public IActionHandler
3709 virtual void execute(CCtrlBase
* /* pCaller */, const string
&/* Params */)
3711 CEntityCL
*selection
= EntitiesMngr
.entity(UserEntity
->selection());
3712 if (selection
!= NULL
)
3714 sint n
= PeopleInterraction
.TeamList
.getIndexFromName(selection
->getEntityName());
3717 const char *msgName
= "TEAM:KICK";
3719 if(GenericMsgHeaderMngr
.pushNameToStream(msgName
, out
))
3721 uint8 teamMember
= (uint8
)n
;
3722 out
.serialEnum(teamMember
);
3724 //nlinfo("impulseCallBack : %s %d sent", msgName, teamMember);
3727 nlwarning("unknown message named '%s'.", msgName
);
3732 REGISTER_ACTION_HANDLER( CAHMilkoKick
, "milko_kick");
3735 // ***************************************************************************
3736 // ***************************************************************************
3737 // ***************************************************************************
3738 // RAW MATERIAL STATS
3739 // ***************************************************************************
3740 // ***************************************************************************
3741 // ***************************************************************************
3744 // ***************************************************************************
3745 static void onMpChangeItemPart(CInterfaceGroup
*wnd
, uint32 itemSheetId
, const string
&statPrefixId
)
3747 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3751 if(!wnd
|| !itemSheetId
)
3754 // get the item sheet
3755 const CItemSheet
*pIS
= dynamic_cast<const CItemSheet
*>(SheetMngr
.get(CSheetId(itemSheetId
)));
3756 if(!pIS
|| pIS
->Family
!=ITEMFAMILY::RAW_MATERIAL
)
3759 // get the group for raw material stat
3760 CInterfaceGroup
*groupMp
= dynamic_cast<CInterfaceGroup
*>(wnd
->getElement(wnd
->getId()+statPrefixId
+INFO_GROUP_MP_STAT
));
3764 // get the combo box
3765 CDBGroupComboBox
*pCB
= dynamic_cast<CDBGroupComboBox
*>(groupMp
->getElement(groupMp
->getId()+":item_part_choice" ));
3769 // get the selection
3770 uint comboSelection
= pCB
->getSelection();
3772 // get the related FaberType
3773 RM_FABER_TYPE::TRMFType faberType
= RM_FABER_TYPE::MPL
;
3775 for(i
=0;i
<RM_FABER_TYPE::NUM_FABER_TYPE
;i
++)
3777 if(pIS
->Mp
.ItemPartBF
& (uint64
)(1 << i
))
3779 if(bitCount
==comboSelection
)
3781 faberType
= RM_FABER_TYPE::TRMFType(i
);
3788 // get the item part
3789 if(!pIS
->canBuildItemPart(faberType
))
3791 const CItemSheet::CMpItemPart
&itemPart
= pIS
->getItemPart(faberType
);
3796 CViewBitmap
*viewBmp
= dynamic_cast<CViewBitmap
*>(groupMp
->getElement(groupMp
->getId()+":icon" ));
3799 // texture name in config.xml
3800 viewBmp
->setTexture(CWidgetManager::getInstance()->getParser()->getDefine( RM_FABER_TYPE::toIconDefineString(faberType
) ));
3806 CViewText
*viewText
= dynamic_cast<CViewText
*>(groupMp
->getElement(groupMp
->getId()+":text" ));
3811 // add the Origin filter.
3812 string originFilterKey
= "iompf" + ITEM_ORIGIN::enumToString((ITEM_ORIGIN::EItemOrigin
)itemPart
.OriginFilter
);
3813 mpCraft
+= CI18N::get(originFilterKey
);
3815 viewText
->setText(mpCraft
);
3819 // **** Build Stat bars
3820 // default: hide all
3821 for(i
=0;i
<RM_FABER_STAT_TYPE::NumRMStatType
;i
++)
3823 // get the stat group
3824 CInterfaceGroup
*groupStat
= dynamic_cast<CInterfaceGroup
*>(groupMp
->getElement(groupMp
->getId()+toString(":stat%d",i
) ));
3826 groupStat
->setActive(false);
3828 // enable only one that are relevant for this item part
3830 for(i
=0;i
<RM_FABER_STAT_TYPE::NumRMStatType
;i
++)
3832 RM_FABER_STAT_TYPE::TRMStatType statType
= RM_FABER_STAT_TYPE::TRMStatType(i
);
3834 // if this stat is not relevant for this item part, don't display it!
3835 if(!RM_FABER_STAT_TYPE::isStatRelevant(faberType
, statType
))
3838 // get the next stat group
3839 CInterfaceGroup
*groupStat
= dynamic_cast<CInterfaceGroup
*>(groupMp
->getElement(groupMp
->getId()+toString(":stat%d",groupIndex
) ));
3842 groupStat
->setActive(true);
3843 // fill text and bar according to stat
3844 CViewText
*statTitle
= dynamic_cast<CViewText
*>(groupStat
->getElement(groupStat
->getId()+":text" ));
3845 CDBViewBar
*statValue
= dynamic_cast<CDBViewBar
*>(groupStat
->getElement(groupStat
->getId()+":bar" ));
3847 statTitle
->setText(RM_FABER_STAT_TYPE::toLocalString(statType
));
3849 statValue
->setValue(itemPart
.Stats
[i
]);
3858 // ***************************************************************************
3859 // MP Item Part selection in a info window
3860 class CAHItemHelpMpChangeItemPart
: public IActionHandler
3863 virtual void execute(CCtrlBase
* /* pCaller */, const string
&Params
)
3865 // get the info window associated
3866 uint infoWindowIndex
;
3867 fromString(Params
, infoWindowIndex
);
3868 if(infoWindowIndex
>=CInterfaceHelp::_InfoWindows
.size())
3870 CInterfaceHelp::CInfoWindow
&infoWindow
= CInterfaceHelp::_InfoWindows
[infoWindowIndex
];
3872 // just to have the correct 'PrefixForExtra' string.
3873 CSheetHelpSetup dummy
;
3874 dummy
.setupDefaultIDs();
3876 // common method for info and botchat
3877 if(infoWindow
.CtrlSheet
)
3879 onMpChangeItemPart(infoWindow
.Window
, infoWindow
.CtrlSheet
->getSheetId(), dummy
.PrefixForExtra
);
3883 REGISTER_ACTION_HANDLER( CAHItemHelpMpChangeItemPart
, "item_help_mp_change_item_part");
3886 // ***************************************************************************
3887 // same, but for BotChat dialog box
3888 class CAHItemBotChatMpChangeItemPart
: public IActionHandler
3891 virtual void execute(CCtrlBase
* /* pCaller */, const string
&Params
)
3893 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3895 // retreive direct params
3896 string wndStr
= getParam(Params
, "wnd");
3897 string dbitem
= getParam(Params
, "dbitem");
3898 string prefix
= getParam(Params
, "prefix");
3900 CInterfaceGroup
*wnd
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(wndStr
));
3901 CCDBNodeLeaf
*node
= NLGUI::CDBManager::getInstance()->getDbProp(dbitem
);
3903 // common method for info and botchat
3906 onMpChangeItemPart(wnd
, node
->getValue32(), prefix
);
3910 REGISTER_ACTION_HANDLER( CAHItemBotChatMpChangeItemPart
, "item_botchat_mp_change_item_part");
3914 // ***************************************************************************
3915 // ***************************************************************************
3917 // ***************************************************************************
3918 // ***************************************************************************
3921 // ***************************************************************************
3923 void updateStatReport ()
3925 // After 30 game minutes, send a stat report
3926 const uint64 time4StatReport
= 60*30*1000;
3927 if ((ingameTime0 () <= time4StatReport
) && (ingameTime1 () > time4StatReport
))
3929 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3930 CAHManager::getInstance()->runActionHandler ("proc", NULL
, "proc_stat_report");
3934 // ***************************************************************************
3936 extern string
getSystemInformation();
3937 class CAHSendStatReport
: public IActionHandler
3941 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
3943 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3944 pIM
->displaySystemInfo(CI18N::get ("uiSendingStatReport"));
3945 string s
= getDebugInformation();
3946 s
+= getSystemInformation();
3950 #ifdef NL_OS_WINDOWS
3952 GetModuleFileNameW(NULL
, name
, 1023);
3953 moduleName
= wideToUtf8(name
);
3957 progname
= CFile::getFilename(moduleName
);
3959 progname
+= "Statistic Report";
3961 bool res
= NLNET::sendEmail ("", "", "", progname
, s
, "");
3963 nlinfo ("Stat report sent");
3965 nlwarning ("Can't send stat report");
3968 REGISTER_ACTION_HANDLER (CAHSendStatReport
, "send_stat_report");
3970 // ***************************************************************************
3971 class CHandlerMkInMode
: public IActionHandler
3974 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
3976 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3978 CCDBNodeLeaf
*pVal
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:MK_MODE", false);
3981 sint32 mode
= pVal
->getValue32() + 1;
3984 pVal
->setValue32(mode
);
3988 REGISTER_ACTION_HANDLER( CHandlerMkInMode
, "mk_inc_mode");
3990 // ***************************************************************************
3991 class CHandlerBrowseFAQ
: public IActionHandler
3994 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
3996 #ifdef NL_OS_WINDOWS
3997 NL3D::UDriver
*Driver
= CViewRenderer::getInstance()->getDriver();
4000 HWND wnd
= (HWND
) Driver
->getDisplay();
4001 ShowWindow(wnd
, SW_MINIMIZE
);
4004 browseFAQ(ClientCfg
.ConfigFile
);
4007 REGISTER_ACTION_HANDLER( CHandlerBrowseFAQ
, "browse_faq");