1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 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/>.
26 #include "nel/misc/xml_auto_ptr.h"
28 #include "group_compas.h"
29 #include "interface_3d_scene.h"
30 #include "../entities.h"
31 #include "nel/gui/action_handler.h"
32 #include "group_map.h"
33 #include "../continent.h"
34 #include "../continent_manager.h"
35 #include "interface_manager.h"
36 #include "../time_client.h"
37 #include "people_interraction.h"
38 #include "../net_manager.h"
39 #include "../string_manager_client.h"
40 #include "view_radar.h"
41 #include "../client_cfg.h"
43 #include "game_share/mission_desc.h"
44 #include "game_share/inventories.h"
45 #include "game_share/animal_type.h"
47 extern NL3D::UCamera MainCam
;
48 extern CEntityManager EntitiesMngr
;
49 extern CContinentManager ContinentMngr
;
50 CCompassDialogsManager
* CCompassDialogsManager::_Instance
= NULL
;
53 using namespace NLMISC
;
54 using namespace STRING_MANAGER
;
56 // ***************************************************************************
57 CCompassTarget::CCompassTarget()
60 Name
= CI18N::get("uiNorth");
64 // ***************************************************************************
65 void CCompassTarget::serial(NLMISC::IStream
&f
)
69 // some position state may not support 'serial'
70 if (_PositionState
&& !_PositionState
->canSave())
72 CCompassTarget defaultCompassTarget
;
73 f
.serial(defaultCompassTarget
);
77 f
.serialCheck(NELID("CTAR"));
78 sint version
= f
.serialVersion(1);
80 // for the name, try to save a string identifier if possible, because language may be changed between
84 ucstring name
; // Serial old version
92 std::string language
= toLowerAscii(ClientCfg
.LanguageCode
);
95 if (_Type
== PosTracker
)
97 CPositionState
*ps
= _PositionState
;
100 nlwarning("ClassName = %s", ps
->getClassName().c_str());
102 nlwarning("%s poly ptr", f
.isReading() ? "reading" : "writing");
110 _PositionState
= NULL
;
113 f
.serialCheck(NELID("_END"));
114 // if language has been modified, then we are not able to display correctly the name, so just
115 // reset the compass to north to avoid incoherency
118 if (toLowerAscii(ClientCfg
.LanguageCode
) != language
)
120 *this = CCompassTarget();
126 // ***************************************************************************
127 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupCompas
, std::string
, "compas");
129 CGroupCompas::CGroupCompas(const TCtorParam
¶m
)
130 : CGroupContainer(param
)
133 std::fill(_TargetTypeColor
, _TargetTypeColor
+ CCompassTarget::NumTypes
, CRGBA::White
);
134 _Target
.setType(CCompassTarget::North
);
135 _Target
.Name
= CI18N::get("uiNorth");
138 _NewTargetSelectedColor
= CRGBA(255, 127, 0);
141 _RadarRangeView
= NULL
;
142 _RadarPos
= 1; // 50 m
143 _DynamicTargetPos
= NULL
;
144 _LastDynamicTargetPos
= 0xFFFFFFFF;
145 _SavedTargetValid
= false;
146 _TargetSetOnce
= false;
148 CCDBNodeLeaf
*pRC
= CDBManager::getInstance()->getDbProp("UI:SAVE:RADAR:USE_CAMERA");
151 ICDBNode::CTextId textId
;
152 pRC
->addObserver( &_UseCameraObs
, textId
);
156 // ***************************************************************************
157 CGroupCompas::~CGroupCompas()
159 CCDBNodeLeaf
*pRC
= CDBManager::getInstance()->getDbProp("UI:SAVE:RADAR:USE_CAMERA");
162 ICDBNode::CTextId textId
;
163 pRC
->removeObserver( &_UseCameraObs
, textId
);
168 // ***************************************************************************
169 bool CGroupCompas::wantSerialConfig() const
171 // NB when the user first start the game, the target will befirst set to 'chiang the strong' when
172 // missions are being received for the first time. If his fail to occur, we just don't
174 return _TargetSetOnce
;
177 // ***************************************************************************
178 void CGroupCompas::serialConfig(NLMISC::IStream
&f
)
183 _SavedTarget
= _Target
;
185 f
.serial(_SavedTarget
);
186 _SavedTargetValid
= true;
190 // ***************************************************************************
191 void CGroupCompas::updateCoords()
193 CGroupContainer::updateCoords();
196 if (_ArrowShape
== NULL
)
198 CInterfaceElement
*element
= getElement (_Id
+":arrow3d");
202 CInterface3DScene
*scene
= dynamic_cast<CInterface3DScene
*>(element
);
205 element
= scene
->getElement (scene
->getId()+":arrow");
209 _ArrowShape
= dynamic_cast<CInterface3DShape
*>(element
);
215 // Get a pointer on the dist view
216 if (_DistView
== NULL
)
218 CInterfaceElement
*element
= getElement(_Id
+":dist");
220 _DistView
= dynamic_cast<CViewText
*>(element
);
223 if (_RadarView
== NULL
)
225 CInterfaceElement
*element
= getElement(_Id
+":visuel:radar");
227 _RadarView
= dynamic_cast<CViewRadar
*>(element
);
230 if (_RadarRangeView
== NULL
)
232 CInterfaceElement
*element
= getElement(_Id
+":visuel:range");
234 _RadarRangeView
= dynamic_cast<CViewText
*>(element
);
238 // ***************************************************************************
239 void CGroupCompas::blink()
242 _StartBlinkTime
= TimeInSec
;
245 // ***************************************************************************
246 NLMISC::CVector2f
CGroupCompas::getNorthPos(const NLMISC::CVector2f
&userPos
) const
248 return NLMISC::CVector2f(userPos
.x
, userPos
.y
+ 1.f
);
251 // ***************************************************************************
252 void CGroupCompas::draw()
254 if ((uint
) _Target
.getType() >= CCompassTarget::NumTypes
) return;
255 CInterfaceManager
*im
= CInterfaceManager::getInstance();
257 if (_RadarView
&& _UseCameraObs
._changed
)
259 _UseCameraObs
._changed
= false;
260 _RadarView
->setUseCamera(_UseCameraObs
._useCamera
);
264 const NLMISC::CVectorD
&userPosD
= UserEntity
->pos();
265 NLMISC::CVector
userPos((float) userPosD
.x
, (float) userPosD
.y
, (float) userPosD
.z
);
266 NLMISC::CVector2f
targetPos(0.f
, 0.f
);
267 // if a position tracker is provided, use it
268 CCompassTarget displayedTarget
= _Target
;
271 if (_UseCameraObs
._useCamera
)
273 CVector projectedFront
= MainCam
.getMatrix().getJ();
274 if (projectedFront
.norm() <= 0.01f
)
276 projectedFront
= MainCam
.getMatrix().getK();
277 projectedFront
.z
= 0.f
;
279 CVector cam
= projectedFront
.normed();
280 myAngle
= (float)atan2(cam
.y
, cam
.x
);
284 const CVector
&front
= UserEntity
->front();
285 myAngle
= (float)atan2 (front
.y
, front
.x
);
288 switch(_Target
.getType())
290 case CCompassTarget::North
:
291 targetPos
.set(userPos
.x
, userPos
.y
+ 1.f
);
293 case CCompassTarget::PosTracker
:
296 if (_Target
.getPositionState())
298 if (_Target
.getPositionState()->getPos(x
, y
))
300 targetPos
.set(x
* 0.001f
, y
* 0.001f
);
303 if (x
== 0 && y
== 0)
305 displayedTarget
= CCompassTarget();
306 targetPos
= getNorthPos(userPos
);
310 case CCompassTarget::Selection
:
312 if (UserEntity
->selection() != CLFECOMMON::INVALID_SLOT
&& UserEntity
->selection() != 0)
314 CEntityCL
*sel
= EntitiesMngr
.entity(UserEntity
->selection());
317 _Target
.Name
= sel
->removeTitleAndShardFromName(sel
->getEntityName());
318 if (_Target
.Name
.empty())
320 _Target
.Name
= sel
->getTitle();
322 targetPos
.set((float)sel
->pos().x
, (float)sel
->pos().y
);
327 displayedTarget
= CCompassTarget();
328 targetPos
= getNorthPos(userPos
);
332 case CCompassTarget::Home
:
335 CCDBNodeLeaf
*pos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":HOME_POINT");
336 sint32 px
= (sint32
) (pos
->getValue64() >> 32);
337 sint32 py
= pos
->getValue32();
338 if (px
!= 0 || py
!= 0)
340 targetPos
.set(px
* 0.001f
, py
* 0.001f
);
344 displayedTarget
= CCompassTarget();
345 targetPos
= getNorthPos(userPos
);
350 targetPos
= _Target
.Pos
;
354 CRGBA color
= _TargetTypeColor
[displayedTarget
.getType()];
356 // apply blinking color if there's one
359 float dt
= (float) (TimeInSec
- _StartBlinkTime
);
360 if (dt
>= COMPASS_BLINK_TIME
)
367 if (dt
> COMPASS_BLINK_TIME
* 0.5f
)
369 blinkAmount
= 2.f
* (COMPASS_BLINK_TIME
- dt
);
373 blinkAmount
= 2.f
* dt
;
375 color
.blendFromui(color
, _NewTargetSelectedColor
, (uint8
) (blinkAmount
* 255.f
));
379 // todo hulud add here guild and bots locations
384 if (_ArrowShape
->getShape().getNumMaterials()>0)
385 _ArrowShape
->getShape().getMaterial(0).setDiffuse(color
);
388 float deltaX
= targetPos
.x
- userPos
.x
;
389 float deltaY
= targetPos
.y
- userPos
.y
;
390 float targetAngle
= (float)atan2 (deltaY
, deltaX
);
391 _ArrowShape
->setRotZ ((float)(targetAngle
- myAngle
)*180.f
/(float)Pi
);
393 // Set the distance text
396 bool active
= (ContinentMngr
.cur() && !ContinentMngr
.cur()->Indoor
);
397 if (_DistView
->getActive() != active
)
398 _DistView
->setActive (active
);
402 float dist
= (float)sqrt(deltaX
*deltaX
+deltaY
*deltaY
);
407 if (displayedTarget
.getType() != CCompassTarget::North
)
411 smprintf (message
, 50, "%.1f ", dist
/1000.0f
);
412 distText
= message
+ CI18N::get("uiKilometerUnit");
416 smprintf (message
, 50, "%.0f ", dist
);
417 distText
= message
+ CI18N::get("uiMeterUnit");
419 distText
= distText
+ " - " + displayedTarget
.Name
;
423 distText
= displayedTarget
.Name
;
425 if (_DistViewText
!= distText
)
427 _DistView
->setText(distText
);
428 _DistViewText
= distText
;
434 CCtrlBase
*toolTip
= getCtrl("tt");
437 if (displayedTarget
.getType() != CCompassTarget::North
)
438 toolTip
->setDefaultContextHelp(CI18N::get("uittCompassDistance"));
440 toolTip
->setDefaultContextHelp(std::string());
443 if (displayedTarget
.Name
!= _CurrTargetName
)
445 _CurrTargetName
= displayedTarget
.Name
;
447 CGroupContainer::draw ();
450 // ***************************************************************************
452 bool CGroupCompas::handleEvent (const NLGUI::CEventDescriptor
&event
)
454 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
456 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
458 if ((_RadarView
!= NULL
) && (_RadarRangeView
!= NULL
))
460 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel
)
462 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
463 _RadarPos
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RADARZOOM")->getValue32();
464 if (eventDesc
.getWheel() > 0)
467 if (_RadarPos
> 0) _RadarPos
--;
472 if (_RadarPos
< 3) _RadarPos
++;
475 NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RADARZOOM")->setValue32(_RadarPos
);
480 return CGroupContainer::handleEvent(event
);
484 // ***************************************************************************
486 void CGroupCompas::setTarget(const CCompassTarget
&target
)
488 if (_LastDynamicTargetPos
!= 0xFFFFFFFF)
490 _LastDynamicTargetPos
= 0xFFFFFFFF;
491 // ask server for no dynamic target update
493 if (GenericMsgHeaderMngr
.pushNameToStream("TARGET:COMPASS_NOT_DYNAMIC", out
))
496 //nlinfo("impulseCallBack : TARGET:COMPASS_NOT_DYNAMIC sent");
499 nlwarning(" unknown message name 'TARGET:COMPASS_NOT_DYNAMIC");
503 _TargetSetOnce
= true;
507 // ***************************************************************************
509 bool CGroupCompas::parse (xmlNodePtr cur
, CInterfaceGroup
*parentGroup
)
512 CGroupContainer::parse (cur
, parentGroup
);
514 // Look for the arrow shape
518 ptr
= xmlGetProp (cur
, (xmlChar
*)"north_color");
519 if (ptr
) _TargetTypeColor
[CCompassTarget::North
] = convertColor(ptr
);
521 ptr
= xmlGetProp (cur
, (xmlChar
*)"selection_color");
522 if (ptr
) _TargetTypeColor
[CCompassTarget::Selection
] = convertColor(ptr
);
524 ptr
= xmlGetProp (cur
, (xmlChar
*)"home_color");
525 if (ptr
) _TargetTypeColor
[CCompassTarget::Home
] = convertColor(ptr
);
527 ptr
= xmlGetProp (cur
, (xmlChar
*)"respawn_color");
528 if (ptr
) _TargetTypeColor
[CCompassTarget::Respawn
] = convertColor(ptr
);
530 ptr
= xmlGetProp (cur
, (xmlChar
*)"continent_landmark_color");
531 if (ptr
) _TargetTypeColor
[CCompassTarget::ContinentLandMark
] = convertColor(ptr
);
533 ptr
= xmlGetProp (cur
, (xmlChar
*)"mission_landmark_color");
534 if (ptr
) _TargetTypeColor
[CCompassTarget::PosTracker
] = convertColor(ptr
); // TODO : see if more colors are needed for animal, mission target, etc.
535 // for now same color for dyanmic tracking of position
537 ptr
= xmlGetProp (cur
, (xmlChar
*)"user_landmark_color");
538 if (ptr
) _TargetTypeColor
[CCompassTarget::UserLandMark
] = convertColor(ptr
);
540 ptr
= xmlGetProp (cur
, (xmlChar
*)"new_target_selected_color");
541 if (ptr
) _NewTargetSelectedColor
= convertColor(ptr
);
544 _DynamicTargetPos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":TARGET");
549 // ***************************************************************************
550 void CGroupCompas::CDBUseCameraObs::update( NLMISC::ICDBNode
*node
)
553 _useCamera
= ((CCDBNodeLeaf
*)node
)->getValueBool();
556 // ***************************************************************************
557 bool buildCompassTargetFromTeamMember(CCompassTarget
&ct
, uint teamMemberId
)
559 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
561 CCDBNodeLeaf
*entityNode
= NLGUI::CDBManager::getInstance()->getDbProp(toString(TEAM_DB_PATH
":%d:UID", teamMemberId
), false);
562 CCDBNodeLeaf
*nameNode
= NLGUI::CDBManager::getInstance()->getDbProp(toString(TEAM_DB_PATH
":%d:NAME", teamMemberId
), false);
563 if (nameNode
&& nameNode
->getValueBool() && entityNode
&& entityNode
->getValue32()!=0 && nameNode
)
565 CSmartPtr
<CTeammatePositionState
> tracker
= new CTeammatePositionState
;
566 tracker
->build(toString(TEAM_DB_PATH
":%d", teamMemberId
));
567 ct
.setPositionState(tracker
);
569 CStringManagerClient
*pSMC
= CStringManagerClient::instance();
571 if (pSMC
->getString(nameNode
->getValue32(), name
))
572 ct
.Name
= CEntityCL::removeTitleAndShardFromName(name
); // TODO : dynamic support for name
574 ct
.Name
= CI18N::get("uiNotReceived");
582 // ***************************************************************************
583 // 0..MAX_INVENTORY_ANIMAL
584 bool buildCompassTargetFromAnimalMember(CCompassTarget
&ct
, uint animalMemberId
)
586 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
589 if(animalMemberId
<MAX_INVENTORY_ANIMAL
+1)
591 ANIMAL_TYPE::EAnimalType at
;
592 at
= (ANIMAL_TYPE::EAnimalType
)NLGUI::CDBManager::getInstance()->getDbProp("SERVER:PACK_ANIMAL:BEAST"+toString(animalMemberId
-1)+":TYPE")->getValue32();
597 case ANIMAL_TYPE::All
: sPrefix
= "uiPATitleMount"; break;
598 case ANIMAL_TYPE::Mount
: sPrefix
= "uiPATitleMount"; break;
599 case ANIMAL_TYPE::Packer
: sPrefix
= "uiPATitlePacker"; break;
600 case ANIMAL_TYPE::Demon
: sPrefix
= "uiPATitleDemon"; break;
603 dbBase
= toString("SERVER:PACK_ANIMAL:BEAST%d", animalMemberId
-1);
604 // +1, its normal, see en.uxt
605 ct
.Name
= CI18N::get(sPrefix
+toString(animalMemberId
));
610 // get if present or not
611 CCDBNodeLeaf
*statusNode
= NLGUI::CDBManager::getInstance()->getDbProp(dbBase
+ ":STATUS", false);
612 if (statusNode
&& ANIMAL_STATUS::isSpawned((ANIMAL_STATUS::EAnimalStatus
)statusNode
->getValue32()) )
614 CSmartPtr
<CAnimalPositionState
> tracker
= new CAnimalPositionState
;
615 tracker
->build(dbBase
);
616 ct
.setPositionState(tracker
);
624 // ***************************************************************************
625 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupCompasMenu
, std::string
, "menu_compas");
627 CGroupCompasMenu::CGroupCompasMenu(const TCtorParam
¶m
)
632 // ***************************************************************************
634 CGroupCompasMenu::~CGroupCompasMenu()
638 // ***************************************************************************
639 bool CGroupCompasMenu::parse(xmlNodePtr cur
, CInterfaceGroup
*parent
/*=NULL*/)
641 if (!CGroupMenu::parse(cur
, parent
)) return false;
642 CXMLAutoPtr
compass((const char*) xmlGetProp (cur
, (xmlChar
*)"compass"));
643 if (compass
) _TargetCompass
= (const char *) compass
;
647 // Helper for sorting landmarks
648 static inline bool UserLandMarksSortPredicate(const CUserLandMark
& lm1
, const CUserLandMark
& lm2
)
650 return toLower(lm1
.Title
) < toLower(lm2
.Title
);
653 // ***************************************************************************
654 // Called when we activate the compass menu
655 void CGroupCompasMenu::setActive (bool state
)
657 if (state
&& getRootMenu())
659 CInterfaceManager
*im
= CInterfaceManager::getInstance();
663 // **** First clear entries
664 // get first SubMenu.
665 uint numLines
= getRootMenu()->getNumLines();
666 uint firstSubMenu
= numLines
;
667 for(k
= 0; k
< numLines
; ++k
)
669 if (getRootMenu()->getSubMenu(k
))
675 // remove lines until first sub menu
676 for(k
= 0; k
< firstSubMenu
; ++k
)
678 getRootMenu()->removeLine(0);
681 // clear all possible targets
684 // Get the 3 sub menus now (since not so many lines)
685 CGroupSubMenu
*missionSubMenu
= NULL
;
686 CGroupSubMenu
*landMarkSubMenu
= NULL
;
687 CGroupSubMenu
*teamSubMenu
= NULL
;
688 CGroupSubMenu
*animalSubMenu
= NULL
;
689 CGroupSubMenu
*dialogsSubMenu
= NULL
;
690 sint missionLineIndex
= 0;
691 sint landMarkLineIndex
= 0;
692 sint teamLineIndex
= 0;
693 sint animalLineIndex
= 0;
694 sint dialogLineIndex
= 0;
695 numLines
= getRootMenu()->getNumLines();
696 for(k
=0;k
<numLines
;k
++)
698 CGroupSubMenu
*subMenu
= getRootMenu()->getSubMenu(k
);
701 if(getRootMenu()->getLineId(k
)=="mission")
702 missionLineIndex
= k
, missionSubMenu
= subMenu
;
703 else if(getRootMenu()->getLineId(k
)=="land_mark")
704 landMarkLineIndex
= k
, landMarkSubMenu
= subMenu
;
705 else if(getRootMenu()->getLineId(k
)=="team")
706 teamLineIndex
= k
, teamSubMenu
= subMenu
;
707 else if(getRootMenu()->getLineId(k
)=="animal")
708 animalLineIndex
= k
, animalSubMenu
= subMenu
;
709 else if(getRootMenu()->getLineId(k
)=="dialogs")
710 dialogLineIndex
= k
, dialogsSubMenu
= subMenu
;
715 // **** append North/Target etc...
720 ct
.setType(CCompassTarget::North
);
721 ct
.Name
= CI18N::get("uiNorth");
722 Targets
.push_back(ct
);
723 getRootMenu()->addLineAtIndex(lineIndex
++, ct
.Name
, "set_compas", toString ("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
725 CCDBNodeLeaf
*pos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":HOME_POINT");
726 sint32 px
= (sint32
) (pos
->getValue64() >> 32);
727 sint32 py
= pos
->getValue32();
728 if (px
!= 0 || py
!= 0)
730 ct
.setType(CCompassTarget::Home
);
731 ct
.Name
= CI18N::get("uiHome");
732 Targets
.push_back(ct
);
733 getRootMenu()->addLineAtIndex(lineIndex
++, ct
.Name
, "set_compas", toString ("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
736 pos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":BIND_POINT");
737 px
= (sint32
) (pos
->getValue64() >> 32);
738 py
= pos
->getValue32();
739 if (px
!= 0 || py
!= 0)
741 ct
.setType(CCompassTarget::Respawn
);
742 ct
.Name
= CI18N::get("uiRespawn");
743 Targets
.push_back(ct
);
744 getRootMenu()->addLineAtIndex(lineIndex
++, ct
.Name
, "set_compas", toString ("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
747 // As of 6/5/2007 : The option to point the selection is always proposed even if no slot is currently targeted
748 //if (UserEntity->selection() != CLFECOMMON::INVALID_SLOT && UserEntity->selection() != 0)
750 /*CEntityCL *entity = EntitiesMngr.entity(UserEntity->selection());
753 //string targetName = CI18N::get("uiTargetTwoPoint") + entity->removeTitleAndShardFromName(entity->getEntityName());
754 string targetName
= CI18N::get("uiTarget");
755 ct
.setType(CCompassTarget::Selection
);
756 ct
.Name
= targetName
;
757 Targets
.push_back(ct
);
758 getRootMenu()->addLineAtIndex(lineIndex
++, targetName
, "set_compas", toString ("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
762 // increment Menu line indexes.
763 missionLineIndex
+= lineIndex
;
764 landMarkLineIndex
+= lineIndex
;
765 teamLineIndex
+= lineIndex
;
766 animalLineIndex
+= lineIndex
;
767 dialogLineIndex
+= lineIndex
;
770 // **** Append Mission in a SubMenu
774 // clear this sub menu
775 missionSubMenu
->reset();
777 // and add each entry
778 bool selectable
= false;
779 for(uint m
= 0; m
< 2; ++m
) // deals with solo & group missions
781 std::string baseDbPath
= m
== 0 ? MISSIONS_DB_PATH
: GROUP_MISSIONS_DB_PATH
;
782 for(k
= 0; k
< MAX_NUM_MISSIONS
; ++k
)
784 for(uint l
= 0; l
<MAX_NUM_MISSION_TARGETS
; ++l
)
786 CCDBNodeLeaf
*textIDLeaf
= NLGUI::CDBManager::getInstance()->getDbProp(baseDbPath
+ toString(":%d:TARGET%d:TITLE", (int) k
, (int) l
), false);
790 if (CStringManagerClient::instance()->getDynString(textIDLeaf
->getValue32(), name
))
792 CCDBNodeLeaf
*leafPosX
= NLGUI::CDBManager::getInstance()->getDbProp(baseDbPath
+ toString(":%d:TARGET%d:X", (int) k
, (int) l
), false);
793 CCDBNodeLeaf
*leafPosY
= NLGUI::CDBManager::getInstance()->getDbProp(baseDbPath
+ toString(":%d:TARGET%d:Y", (int) k
, (int) l
), false);
794 if (leafPosX
&& leafPosY
)
797 CSmartPtr
<CNamedEntityPositionState
> tracker
= new CNamedEntityPositionState
;
798 tracker
->build(textIDLeaf
, leafPosX
, leafPosY
);
799 ct
.setPositionState(tracker
);
801 Targets
.push_back(ct
);
802 missionSubMenu
->addLine(ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
811 getRootMenu()->setSelectable(missionLineIndex
, selectable
);
812 getRootMenu()->setGrayedLine(missionLineIndex
, !selectable
);
815 // **** Append LandMarks in a SubMenu
818 uint numLMLines
= landMarkSubMenu
->getNumLines();
819 uint firstLMSubMenu
= numLMLines
;
820 for(k
= 0; k
< numLMLines
; ++k
)
822 if (landMarkSubMenu
->getSubMenu(k
))
828 // remove lines until first sub menu
829 for(k
= 0; k
< firstLMSubMenu
; ++k
)
831 landMarkSubMenu
->removeLine(0);
834 // Get the userlm sub menus now (before adding the continent lm)
835 std::vector
<CGroupSubMenu
*> landMarkSubMenus
;
836 landMarkSubMenus
.resize(CUserLandMark::UserLandMarkTypeCount
);
838 for(k
=0;k
<landMarkSubMenus
.size();k
++)
840 landMarkSubMenus
[k
] = landMarkSubMenu
->getSubMenu(k
);
841 landMarkSubMenus
[k
]->reset();
844 CContinent
*currCont
= ContinentMngr
.cur();
845 bool selectable
= false;
848 uint contLandMarkIndex
= 0;
849 // Continent landmarks
850 for(k
= 0; k
< currCont
->ContLandMarks
.size(); ++k
)
851 if ((currCont
->ContLandMarks
[k
].Type
== CContLandMark::Capital
) ||
852 (currCont
->ContLandMarks
[k
].Type
== CContLandMark::Village
))
855 ct
.setType(CCompassTarget::ContinentLandMark
);
856 ct
.Pos
= currCont
->ContLandMarks
[k
].Pos
;
857 ct
.Name
= CStringManagerClient::getPlaceLocalizedName(currCont
->ContLandMarks
[k
].TitleTextID
);
858 Targets
.push_back(ct
);
859 landMarkSubMenu
->addLineAtIndex(contLandMarkIndex
++, ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
863 if (currCont
->ContLandMarks
.size() != 0 && currCont
->UserLandMarks
.size() != 0)
865 landMarkSubMenu
->addSeparatorAtIndex(contLandMarkIndex
++);
869 // Sort the landmarks
870 std::vector
<CUserLandMark
> sortedLandmarks(currCont
->UserLandMarks
);
871 std::sort(sortedLandmarks
.begin(), sortedLandmarks
.end(), UserLandMarksSortPredicate
);
873 for(k
= 0; k
< sortedLandmarks
.size(); ++k
)
875 if (sortedLandmarks
[k
].Type
< CUserLandMark::UserLandMarkTypeCount
)
878 ct
.setType(CCompassTarget::UserLandMark
);
879 ct
.Pos
= sortedLandmarks
[k
].Pos
;
880 ct
.Name
= sortedLandmarks
[k
].Title
.toUtf8();
881 Targets
.push_back(ct
);
882 landMarkSubMenus
[sortedLandmarks
[k
].Type
]->addLine(ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
888 for(k
=0;k
<landMarkSubMenus
.size();k
++)
890 landMarkSubMenu
->setHiddenLine(k
+ contLandMarkIndex
, landMarkSubMenus
[k
]->getNumLines() <= 0);
896 getRootMenu()->setSelectable(landMarkLineIndex
, selectable
);
897 getRootMenu()->setGrayedLine(landMarkLineIndex
, !selectable
);
900 // **** Append Team Members in a SubMenu
903 // clear this sub menu
904 teamSubMenu
->reset();
906 bool selectable
= false;
907 for (k
= 0; k
< MaxNumPeopleInTeam
; k
++)
910 if (buildCompassTargetFromTeamMember(ct
, k
))
912 Targets
.push_back(ct
);
913 teamSubMenu
->addLine(ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
919 getRootMenu()->setSelectable(teamLineIndex
, selectable
);
920 getRootMenu()->setGrayedLine(teamLineIndex
, !selectable
);
923 // **** Append Animal Members in a SubMenu
926 // clear this sub menu
927 animalSubMenu
->reset();
929 bool selectable
= false;
930 for (k
= 0; k
< 1 + MAX_INVENTORY_ANIMAL
+1; k
++)
933 if (buildCompassTargetFromAnimalMember(ct
, k
))
935 Targets
.push_back(ct
);
936 animalSubMenu
->addLine(ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
942 getRootMenu()->setSelectable(animalLineIndex
, selectable
);
943 getRootMenu()->setGrayedLine(animalLineIndex
, !selectable
);
946 // **** Append Dialogs Members in a SubMenu
949 // clear this sub menu
950 dialogsSubMenu
->reset();
951 bool selectable
= false;
953 // and add each entry
954 const std::vector
<CCompassDialogsManager::CCompassDialogsEntry
> & entries
= CCompassDialogsManager::getInstance().getEntries();
955 const uint size
= (uint
)entries
.size();
956 for( uint i
= 0; i
< size
; ++i
)
959 if (CStringManagerClient::instance()->getDynString(entries
[i
].Text
, ct
.Name
))
961 CSmartPtr
<CDialogEntityPositionState
> tracker
= new CDialogEntityPositionState( i
);
962 ct
.setPositionState(tracker
);
963 Targets
.push_back(ct
);
964 dialogsSubMenu
->addLine(ct
.Name
, "set_compas", toString("compass=%s|id=%d|menu=%s", _TargetCompass
.c_str(), (int) Targets
.size() - 1, _Id
.c_str()));
969 getRootMenu()->setSelectable(dialogLineIndex
, selectable
);
970 getRootMenu()->setGrayedLine(dialogLineIndex
, !selectable
);
974 CGroupMenu::setActive (state
);
977 // ***************************************************************************
978 // Called from a compass menu
979 class CHandlerSetCompas
: public IActionHandler
981 void execute (CCtrlBase
* /* pCaller */, const std::string
&sParams
)
983 std::string compassID
= getParam(sParams
, "compass");
984 std::string menuID
= getParam(sParams
, "menu");
985 CInterfaceManager
*im
= CInterfaceManager::getInstance();
986 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(compassID
));
988 CGroupCompasMenu
*gcm
= dynamic_cast<CGroupCompasMenu
*>(CWidgetManager::getInstance()->getElementFromId(menuID
));
991 std::string id
= getParam(sParams
, "id");
992 if (!fromString(id
, index
)) return;
993 if ((uint
) index
< (uint
) gcm
->Targets
.size())
995 gc
->setTarget(gcm
->Targets
[index
]);
998 CWidgetManager::getInstance()->setTopWindow(gc
);
1002 REGISTER_ACTION_HANDLER( CHandlerSetCompas
, "set_compas");
1005 // ***************************************************************************
1006 // Called from a Team member menu
1007 class CHandlerSetTeamCompas
: public IActionHandler
1009 void execute (CCtrlBase
* /* pCaller */, const std::string
&sParams
)
1011 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1013 // get the compass window
1014 std::string compassID
= getParam(sParams
, "compass");
1016 // Get the team member index
1019 if (PeopleInterraction
.getPeopleFromCurrentMenu(list
, peopleIndex
))
1021 if (list
== &PeopleInterraction
.TeamList
) // check for good list
1023 // If can CompassTarget this team member
1025 if(buildCompassTargetFromTeamMember(ct
, peopleIndex
))
1027 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(compassID
));
1031 gc
->setActive(true);
1033 CWidgetManager::getInstance()->setTopWindow(gc
);
1040 REGISTER_ACTION_HANDLER( CHandlerSetTeamCompas
, "set_team_compas");
1042 // ***************************************************************************
1043 class CHandlerSetCompassNorth
: public IActionHandler
1045 void execute (CCtrlBase
* /* pCaller */, const std::string
&sParams
)
1047 std::string compassID
= getParam(sParams
, "compass");
1048 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1049 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(compassID
));
1051 gc
->setTarget(CCompassTarget());
1054 REGISTER_ACTION_HANDLER( CHandlerSetCompassNorth
, "set_compass_north");
1057 class CCompassDialogsStringCallback
: public IStringWaitCallback
1059 virtual void onDynStringAvailable(uint
/* stringId */, const std::string
&value
)
1061 uint size
= (uint
)CCompassDialogsManager::getInstance()._Entries
.size();
1062 for ( uint i
= 0; i
< size
; i
++)
1065 if ( CStringManagerClient::instance()->getDynString(CCompassDialogsManager::getInstance()._Entries
[i
].Text
, name
) )
1067 if ( value
== name
)
1069 CCompassDialogsManager::getInstance()._Entries
[i
] = CCompassDialogsManager::getInstance()._Entries
.back();
1070 CCompassDialogsManager::getInstance()._Entries
.pop_back();
1079 void CCompassDialogsManager::removeEntry(uint32 text
)
1081 CCompassDialogsStringCallback
* callback
= new CCompassDialogsStringCallback
;
1082 CStringManagerClient::instance()->waitDynString( text
,callback
);