1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2019 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2014-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "group_map.h"
26 #include "interface_manager.h"
27 #include "../continent_manager.h"
28 #include "../continent.h"
29 #include "../zone_util.h"
30 #include "../user_entity.h"
31 #include "nel/gui/ctrl_button.h"
32 #include "nel/gui/group_editbox.h"
33 #include "nel/gui/dbgroup_combo_box.h"
34 #include "../string_manager_client.h"
35 #include "nel/gui/group_container.h"
36 #include "nel/gui/action_handler.h"
37 #include "../dummy_progress.h"
38 #include "group_compas.h"
39 #include "group_html_cs.h"
40 #include "../connection.h"
41 #include "../net_manager.h"
42 #include "people_interraction.h" // for MaxNumPeopleInTeam
43 #include "../sheet_manager.h" // for MaxNumPeopleInTeam
44 #include "../global.h"
45 #include "nel/gui/ctrl_quad.h"
46 #include "nel/gui/lua_ihm.h"
48 #include "nel/misc/xml_auto_ptr.h"
49 #include "game_share/mission_desc.h"
50 #include "game_share/inventories.h"
51 #include "game_share/animal_type.h"
53 #include "nel/3d/u_material.h"
54 #include "nel/3d/u_texture.h"
55 #include "nel/3d/u_scene.h"
56 #include "../entities.h"
58 #include "nel/misc/vector_2f.h"
59 #include "nel/misc/bitmap.h"
60 #include "nel/misc/path.h"
61 #include "nel/misc/file.h"
62 #include "nel/misc/uv.h"
63 #include "nel/misc/i18n.h"
64 #include "../r2/editor.h"
66 #include "game_share/scenario_entry_points.h"
74 extern CContinentManager ContinentMngr
;
75 extern NL3D::UDriver
*Driver
;
76 extern NL3D::UScene
*Scene
;
77 extern CEntityManager EntitiesMngr
;
79 using namespace NLMISC
;
83 using NLMISC::CBitMemStream
;
84 using namespace STRING_MANAGER
;
89 static CGroupMap
*LastClickedMap
= NULL
;
90 static CCtrlButton
*LastSelectedLandMark
= NULL
;
91 static bool UseUserPositionForLandMark
= false;
92 static const char *WIN_LANDMARK_NAME
="ui:interface:enter_landmark_name";
94 // Loaded position of user landmark types
95 static std::vector
<uint
> LoadedPosition
;
100 NLMISC::CRGBA
CUserLandMark::_LandMarksColor
[CUserLandMark::UserLandMarkTypeCount
];
104 const uint32 ISLAND_PIXEL_PER_METER
= 2;
106 static void setupFromZoom(CViewBase
*pVB
, CContLandMark::TContLMType t
, float fMeterPerPixel
);
108 // calculate distance (squared) between two points
109 static float distsqr(const CVector2f a
, const CVector2f b
)
111 return pow(a
.x
- b
.x
, 2) + pow(a
.y
- b
.y
, 2);
114 // popup the landmark name dialog
116 static void popupLandMarkNameDialog()
118 // pop the rename dialog
119 CInterfaceManager
*im
= CInterfaceManager::getInstance();
120 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId(WIN_LANDMARK_NAME
));
126 CWidgetManager::getInstance()->setTopWindow(gc
);
129 CGroupEditBox
*eb
= dynamic_cast<CGroupEditBox
*>(gc
->getGroup("eb"));
132 // Load ComboBox for Landmarks & sort entries
133 CDBGroupComboBox
*cb
= dynamic_cast<CDBGroupComboBox
*>(gc
->getGroup("landmarktypes"));
136 if (LastSelectedLandMark
)
138 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(LastSelectedLandMark
->getParent());
141 const CUserLandMark userLM
= map
->getUserLandMark(LastSelectedLandMark
);
143 NLGUI::CDBManager::getInstance()->getDbProp( "UI:TEMP:LANDMARKTYPE" )->setValue8(cb
->getTextPos(userLM
.Type
));
144 eb
->setInputString(userLM
.Title
.toUtf8());
148 NLGUI::CDBManager::getInstance()->getDbProp( "UI:TEMP:LANDMARKTYPE" )->setValue8(cb
->getTextPos(CUserLandMark::Misc
));
149 eb
->setInputString(string());
152 CWidgetManager::getInstance()->setCaptureKeyboard(eb
);
153 eb
->setSelectionAll();
156 static void closeLandMarkNameDialog()
158 LoadedPosition
.clear();
159 CInterfaceManager
*im
= CInterfaceManager::getInstance();
160 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId(WIN_LANDMARK_NAME
));
162 gc
->setActive(false);
165 //============================================================================================================
167 //============================================================================================================
169 NL3D::UMaterial
CGroupMap::CPolyButton::LineMat
;
171 //============================================================================================================
172 CGroupMap::CPolyButton::CPolyButton()
173 : CCtrlBase(TCtorParam())
177 // create material for displaying the button
180 // create material for the world map
181 LineMat
= Driver
->createMaterial();
182 if (!LineMat
.empty())
185 LineMat
.setSrcBlend(NL3D::UMaterial::srcalpha
);
186 LineMat
.setDstBlend(NL3D::UMaterial::invsrcalpha
);
187 LineMat
.setBlend(true);
188 LineMat
.setZFunc(NL3D::UMaterial::always
);
189 LineMat
.setZWrite(false);
190 LineMat
.setColor(CRGBA::Red
);
197 //============================================================================================================
198 bool CGroupMap::CPolyButton::handleEvent (const NLGUI::CEventDescriptor
&event
)
200 if (CCtrlBase::handleEvent(event
)) return true;
201 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
203 CInterfaceManager
*im
= CInterfaceManager::getInstance();
204 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
206 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
)
208 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
212 if (contains(CVector2f((float)eventDesc
.getX(), (float)eventDesc
.getY())))
216 for (i
= 0; i
< Map
->getCurMap()->Children
.size(); ++i
)
218 if (ID
== Map
->getCurMap()->Children
[i
].ZoneName
)
225 CWidgetManager::getInstance()->setCapturePointerLeft(NULL
);
227 Map
->setMap(Map
->getCurMap()->Children
[i
].Name
);
232 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown
)
234 if (contains(CVector2f((float)eventDesc
.getX(), (float)eventDesc
.getY())))
236 CWidgetManager::getInstance()->setCapturePointerLeft(this);
245 //============================================================================================================
246 void CGroupMap::CPolyButton::updateCoords()
249 PolysReal
.resize(Polys
.size());
250 for (p
= 0; p
< Polys
.size(); ++p
)
252 PolysReal
[p
].Vertices
.resize(Polys
[p
].Vertices
.size());
253 for (i
= 0; i
< Polys
[p
].Vertices
.size(); ++i
)
257 Map
->worldToMap(mapCoords
, Polys
[p
].Vertices
[i
]);
258 Map
->mapToScreen(x
, y
, mapCoords
);
259 PolysReal
[p
].Vertices
[i
] = CVector2f((float)x
,(float)y
);
263 ZoneReal
.VPoints
.resize(Zone
.VPoints
.size());
264 for (i
= 0; i
< Zone
.VPoints
.size(); ++i
)
268 Map
->worldToMap(mapCoords
, Zone
.VPoints
[i
]);
269 Map
->mapToScreen(x
, y
, mapCoords
);
270 ZoneReal
.VPoints
[i
] = NLLIGO::CPrimVector(CVector2f((float)x
,(float)y
));
274 //============================================================================================================
275 float CGroupMap::getActualMaxScale() const
277 return ClientCfg
.R2EDEnabled
? _ScaleMaxR2
: _ScaleMax
;
280 //============================================================================================================
281 void CGroupMap::CPolyButton::drawPolyButton()
283 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
284 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
287 rVR
.getScreenOOSize(oow
, ooh
);
290 const std::vector
<CCtrlBase
*> &rCUP
= CWidgetManager::getInstance()->getCtrlsUnderPointer();
291 for (uint32 i
= 0; i
< rCUP
.size(); ++i
)
299 for (uint32 p = 0; p < PolysReal.size(); ++p)
301 for (uint32 i = 0; i < PolysReal[p].Vertices.size(); ++i)
304 l.V0 = PolysReal[p].Vertices[i];
305 if (i != (PolysReal[p].Vertices.size()-1))
306 l.V1 = PolysReal[p].Vertices[i+1];
308 l.V1 = PolysReal[p].Vertices[0];
315 Driver->drawLine(l, LineMat);
321 LineMat
.setColor(CRGBA(255,255,255,64)); // LineMat.setColor(CRGBA(165,38,6,128));
323 return; // LineMat.setColor(CRGBA(255,255,255,64));
325 for (uint32 p
= 0; p
< PolysReal
.size(); ++p
)
327 for (uint32 i
= 0; i
< (PolysReal
[p
].Vertices
.size()-2); ++i
)
330 t
.V0
= PolysReal
[p
].Vertices
[0];
331 t
.V1
= PolysReal
[p
].Vertices
[i
+1];
332 t
.V2
= PolysReal
[p
].Vertices
[i
+2];
341 Driver
->drawTriangle(t
, LineMat
);
346 //============================================================================================================
347 bool CGroupMap::CPolyButton::build(const NLLIGO::CPrimZone
&concavePoly
, CGroupMap
*pMap
, const string
&sID
)
349 static int gStat
= 0;
350 _Id
= pMap
->getId() + ":polybut" + toString(gStat
++);
357 for (uint32 i
= 0; i
< concavePoly
.VPoints
.size(); ++i
)
358 p
.Vertices
.push_back(CVector(concavePoly
.VPoints
[i
].x
, concavePoly
.VPoints
[i
].y
, 0));
360 std::list
<CPolygon
> outputPolygons
;
363 if (p
.toConvexPolygons (outputPolygons
, id
))
365 std::list
<CPolygon
>::iterator it
= outputPolygons
.begin();
366 while (it
!= outputPolygons
.end())
369 for (uint32 i
= 0; i
< it
->Vertices
.size(); ++i
)
370 poly
.Vertices
.push_back(CVector2f(it
->Vertices
[i
].x
, it
->Vertices
[i
].y
));
371 Polys
.push_back(poly
);
377 nlwarning("cannot convert to convex poly");
383 //============================================================================================================
384 bool CGroupMap::CPolyButton::contains(const NLMISC::CVector2f
&pos
)
387 for (uint32 p = 0; p < PolysReal.size(); ++p)
389 if (PolysReal[p].contains(pos))
394 return ZoneReal
.contains(pos
);
397 //============================================================================================================
399 //============================================================================================================
401 //============================================================================================================
403 NLMISC_REGISTER_OBJECT(CViewBase
, CGroupMap
, std::string
, "map");
405 CGroupMap::CGroupMap(const TCtorParam
¶m
)
406 : CInterfaceGroup(param
)
410 _WorldOffset
.x
= 0.f
;
411 _WorldOffset
.y
= 0.f
;
419 _PlayerPosMaterial
= NULL
;
425 _MapLoadFailure
= false;
426 _PlayerPosLoadFailure
= false;
427 _WorldSheet
= dynamic_cast<CWorldSheet
*>(SheetMngr
.get(CSheetId("ryzom.world")));
429 _CurContinent
= NULL
;
432 _RightClickLastPos
.set(0.f
, 0.f
);
433 // make room for mission targets
434 _MissionLM
.resize(2 * MAX_NUM_MISSIONS
* MAX_NUM_MISSION_TARGETS
, 0);
435 _MissionTargetTextIDs
.resize(2 * MAX_NUM_MISSIONS
* MAX_NUM_MISSION_TARGETS
, 0);
436 _MissionTargetTextReceived
.resize(2 * MAX_NUM_MISSIONS
* MAX_NUM_MISSION_TARGETS
, false);
437 _OldPlayerPos
.set(0.f
, 0.f
);
438 _PlayerPos
.set(0.f
, 0.f
);
442 _LandmarkFilter
.clear();
443 _MatchedLandmarks
.clear();
454 _MapMode
= MapMode_Normal
;
455 _RespawnSelected
= 0;
456 _RespawnSelectedBitmap
= NULL
;
458 _WorldToMapDeltaX
= 0.f
;
459 _WorldToMapDeltaY
= 0.f
;
461 _VisibleWorldMin
.set(0.f
, 0.f
);
462 _VisibleWorldMax
.set(0.f
, 0.f
);
464 _MeterPerPixel
= 0.f
;
466 _FrustumViewColor
= CRGBA(255, 255, 255, 255);
467 _FrustumViewColorOver
= CRGBA(255, 255, 255, 127);
468 _FrustumOverBlendFactor
= 0.f
;
469 _FrustumViewBlendTimeInMs
= 300;
470 _SelectionAxisH
= NULL
;
471 _SelectionAxisV
= NULL
;
475 _PanStartDateInMs
= 0;
476 _DeltaTimeBeforePanInMs
= 0;
477 _DeltaPosBeforePan
= 0;
479 _LuaLoadMapEntered
= false;
482 //============================================================================================================
483 CGroupMap::~CGroupMap()
487 if (!_MapMaterial
.empty())
488 Driver
->deleteMaterial(_MapMaterial
);
489 if (!_PlayerPosMaterial
.empty())
490 Driver
->deleteMaterial(_PlayerPosMaterial
);
492 for(TDecos::iterator it
= _Decos
.begin(); it
!= _Decos
.end(); ++it
)
494 (*it
)->onRemove(*this);
499 //============================================================================================================
500 void CGroupMap::addDeco(IDeco
*deco
)
503 if (_Decos
.count(deco
))
505 nlwarning("Deco added twice.");
510 deco
->onUpdate(*this);
513 //============================================================================================================
514 void CGroupMap::removeDeco(IDeco
*deco
)
517 TDecos::iterator it
= _Decos
.find(deco
);
518 if (it
!= _Decos
.end())
520 deco
->onRemove(*this);
525 nlwarning("Deco not found");
529 //============================================================================================================
530 /** Load infos about a landmark
532 static void loadLandmarkInfo(xmlNodePtr cur
, const std::string
&prefix
, CLandMarkOptions
&dest
)
535 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_tex_normal").c_str());
536 if (ptr
) dest
.LandMarkTexNormal
= (const char *) ptr
;
537 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_tex_over").c_str());
538 if (ptr
) dest
.LandMarkTexOver
= (const char *) ptr
;
539 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_tex_pushed").c_str());
540 if (ptr
) dest
.LandMarkTexPushed
= (const char *) ptr
;
541 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_menu").c_str());
542 if (ptr
) dest
.LandMarkMenu
= (const char *) ptr
;
543 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_color_normal").c_str());
544 if (ptr
) dest
.ColorNormal
= CCtrlBase::convertColor(ptr
);
545 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_color_over").c_str());
546 if (ptr
) dest
.ColorOver
= CCtrlBase::convertColor(ptr
);
547 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)(prefix
+ "_landmark_color_pushed").c_str());
548 if (ptr
) dest
.ColorPushed
= CCtrlBase::convertColor(ptr
);
552 //============================================================================================================
553 CViewBitmap
*CGroupMap::newSelectionAxis(NLMISC::CRGBA color
)
555 CViewBitmap
*axis
= new CViewBitmap(TCtorParam());
556 axis
->setActive(false);
557 axis
->setTexture("blank.tga");
558 axis
->setModulateGlobalColor(false);
560 axis
->setParent(this);
561 axis
->setColor(color
);
562 axis
->setScale(true);
566 //============================================================================================================
567 bool CGroupMap::parse(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
569 if (!CInterfaceGroup::parse(cur
, parentGroup
)) return false;
570 CXMLAutoPtr
ptr((const char*) xmlGetProp( cur
, (xmlChar
*)"min_h" ));
571 if (ptr
) fromString((const char*) ptr
, _MinH
);
572 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"max_h" );
573 if (ptr
) fromString((const char*)ptr
, _MaxH
);
574 /*ptr = (char*) xmlGetProp( cur, (xmlChar*)"min_w" );
575 if (ptr) fromString((const char*)ptr, _MinW);*/
577 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"map_mode" );
580 string sTmp
= ptr
.str();
581 if (sTmp
== "normal")
582 _MapMode
= MapMode_Normal
;
583 else if (sTmp
== "death")
584 _MapMode
= MapMode_Death
;
585 else if (sTmp
== "spawn_squad")
586 _MapMode
= MapMode_SpawnSquad
;
589 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"frustum_view_color" );
592 _FrustumViewColor
= convertColor (ptr
);
594 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"frustum_view_color_over" );
597 _FrustumViewColorOver
= convertColor (ptr
);
599 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"frustum_view_blend_time_in_ms" );
602 fromString((const char*)ptr
, _FrustumViewBlendTimeInMs
);
608 if (_MapMaterial
.empty())
610 // create material for the world map
611 _MapMaterial
= Driver
->createMaterial();
612 if (!_MapMaterial
.empty())
614 _MapMaterial
.initUnlit();
615 _MapMaterial
.setSrcBlend(NL3D::UMaterial::srcalpha
);
616 _MapMaterial
.setDstBlend(NL3D::UMaterial::invsrcalpha
);
617 _MapMaterial
.setBlend(true);
618 _MapMaterial
.setZFunc(NL3D::UMaterial::always
);
619 _MapMaterial
.setZWrite(false);
621 _MapMaterial
.texEnvOpRGB(0, NL3D::UMaterial::Modulate
);
622 _MapMaterial
.texEnvArg0RGB(0, NL3D::UMaterial::Texture
, NL3D::UMaterial::SrcColor
);
623 _MapMaterial
.texEnvArg1RGB(0, NL3D::UMaterial::Diffuse
, NL3D::UMaterial::SrcColor
);
624 _MapMaterial
.texEnvOpAlpha(0, NL3D::UMaterial::Modulate
);
625 _MapMaterial
.texEnvArg0Alpha(0, NL3D::UMaterial::Texture
, NL3D::UMaterial::SrcAlpha
);
626 _MapMaterial
.texEnvArg1Alpha(0, NL3D::UMaterial::Diffuse
, NL3D::UMaterial::SrcAlpha
);
628 _MapMaterial
.texEnvOpRGB(1, NL3D::UMaterial::Modulate
);
629 _MapMaterial
.texEnvArg0RGB(1, NL3D::UMaterial::Previous
, NL3D::UMaterial::SrcColor
);
630 _MapMaterial
.texEnvArg1RGB(1, NL3D::UMaterial::Texture
, NL3D::UMaterial::SrcAlpha
);
631 _MapMaterial
.texEnvOpAlpha(1, NL3D::UMaterial::Replace
);
632 _MapMaterial
.texEnvArg0Alpha(1, NL3D::UMaterial::Previous
, NL3D::UMaterial::SrcAlpha
);
635 if (_PlayerPosMaterial
.empty())
637 // create material for the world map
638 _PlayerPosMaterial
= Driver
->createMaterial();
639 if (!_PlayerPosMaterial
.empty())
641 _PlayerPosMaterial
.initUnlit();
642 _PlayerPosMaterial
.setSrcBlend(NL3D::UMaterial::srcalpha
);
643 _PlayerPosMaterial
.setDstBlend(NL3D::UMaterial::invsrcalpha
);
644 _PlayerPosMaterial
.setBlend(true);
645 _PlayerPosMaterial
.setZFunc(NL3D::UMaterial::always
);
646 _PlayerPosMaterial
.setZWrite(false);
650 // continent landmarks
651 loadLandmarkInfo(cur
, "continent", _ContinentLMOptions
);
652 loadLandmarkInfo(cur
, "mission", _MissionLMOptions
);
653 loadLandmarkInfo(cur
, "user", _UserLMOptions
);
654 loadLandmarkInfo(cur
, "target", _TargetLMOptions
);
655 // home aspect depends on race
656 EGSPD::CPeople::TPeople people
= EGSPD::CPeople::Fyros
;
657 if (PlayerSelectedSlot
< CharacterSummaries
.size())
659 people
= CharacterSummaries
[people
].People
;
663 case EGSPD::CPeople::Fyros
: loadLandmarkInfo(cur
, "home_fyros", _HomeLMOptions
); break;
664 case EGSPD::CPeople::Matis
: loadLandmarkInfo(cur
, "home_matis", _HomeLMOptions
); break;
665 case EGSPD::CPeople::Zorai
: loadLandmarkInfo(cur
, "home_zorai", _HomeLMOptions
); break;
666 case EGSPD::CPeople::Tryker
: loadLandmarkInfo(cur
, "home_tryker", _HomeLMOptions
); break;
669 loadLandmarkInfo(cur
, "respawn", _RespawnLMOptions
);
671 loadLandmarkInfo(cur
, "animal", _AnimalLMOptions
);
672 // animal(in stable) landmark
673 loadLandmarkInfo(cur
, "animal_stable", _AnimalStableLMOptions
);
674 // animal(dead) landmark
675 loadLandmarkInfo(cur
, "animal_dead", _AnimalDeadLMOptions
);
677 loadLandmarkInfo(cur
, "teammate", _TeammateLMOptions
);
680 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"player_pos_tex" );
681 if (ptr
) _PlayerPosTexName
= (const char *) ptr
;
682 // name of compass for targeting
683 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"compass" );
684 if (ptr
) _CompassId
= (const char *) ptr
;
686 if (_MapMode
== MapMode_Normal
)
688 // create home, target & respawn landmarks
689 _TargetLM
= createLandMarkButton(_TargetLMOptions
);
692 _TargetLM
->setParent(this);
695 _HomeLM
= createLandMarkButton(_HomeLMOptions
);
698 _HomeLM
->setParent(this);
700 _HomeLM
->setDefaultContextHelp(NLMISC::CI18N::get("uiHome"));
703 // create animals Landmark: pack Animals.
704 _AnimalLM
.resize(MAX_INVENTORY_ANIMAL
);
705 for(uint i
=0;i
<_AnimalLM
.size();i
++)
707 _AnimalLM
[i
] = createLandMarkButton(_AnimalLMOptions
);
710 _AnimalLM
[i
]->setParent(this);
711 addCtrl(_AnimalLM
[i
]);
712 _AnimalLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get(NLMISC::toString("uiPATitleMount%d", i
+1)));
716 // create teammates Landmark
717 _TeammateLM
.resize(MaxNumPeopleInTeam
);
718 for(uint i
=0; i
< MaxNumPeopleInTeam
; i
++)
720 _TeammateLM
[i
] = createLandMarkButton(_TeammateLMOptions
);
723 _TeammateLM
[i
]->setParent(this);
724 addCtrl(_TeammateLM
[i
]);
725 _TeammateLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get(NLMISC::toString("uittLMTeam%d",i
)));
731 _ScaleMax
= ClientCfg
.MaxMapScale
;
732 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"scale_max" );
733 if (ptr
) fromString((const char *) ptr
, _ScaleMax
);
735 _ScaleMaxR2
= ClientCfg
.R2EDMaxMapScale
;
736 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"scale_max_r2" );
737 if (ptr
) fromString((const char *) ptr
, _ScaleMaxR2
);
739 if ((_MapMode
== MapMode_Death
) || (_MapMode
== MapMode_SpawnSquad
))
741 string stmp
= "w_answer_16_valid.tga";
742 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"respawn_selected" );
743 if (ptr
) stmp
= (const char*)ptr
;
744 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"respawn_button" );
745 if (ptr
) _RespawnButton
= (const char*)ptr
;
746 _RespawnSelectedBitmap
= new CViewBitmap(CViewBase::TCtorParam());
747 static int statRP
= 0;
748 _RespawnSelectedBitmap
->setId(getId()+":rp"+toString(statRP
++));
749 _RespawnSelectedBitmap
->setTexture(stmp
);
750 _RespawnSelectedBitmap
->setParent(this);
751 _RespawnSelectedBitmap
->setParentPosRef(Hotspot_MM
);
752 _RespawnSelectedBitmap
->setPosRef(Hotspot_MM
);
753 addView(_RespawnSelectedBitmap
);
755 //CCtrlBaseButton *pCB = dynamic_cast<CCtrlBaseButton*>(CWidgetManager::getInstance()->getElementFromId(_RespawnButton));
756 //if (pCB != NULL) pCB->setActive(false);
758 nlassert(!_FrustumView
);
759 CViewBase::TCtorParam param
;
760 _FrustumView
= new CCtrlQuad( param
);
761 _FrustumView
->setActive(false);
762 addView(_FrustumView
);
763 _FrustumView
->setParent(this);
764 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"frustum_view_texture" );
773 value
= "r2_frustum.tga";
775 _FrustumView
->setTexture(value
);
776 _FrustumView
->setModulateGlobalColor(false);
778 nlassert(!_SelectionAxisH
);
779 nlassert(!_SelectionAxisV
);
780 CRGBA axisColor
= CRGBA(0, 0, 0, 127);
781 ptr
= (char*) xmlGetProp( cur
, (xmlChar
*)"selection_axis_color" );
784 axisColor
= convertColor(ptr
);
786 _SelectionAxisH
= newSelectionAxis(axisColor
);
787 _SelectionAxisV
= newSelectionAxis(axisColor
);
790 R2::CScenarioEntryPoints
&sep
= R2::CScenarioEntryPoints::getInstance();
793 sep
.loadCompleteIslands();
794 const R2::CScenarioEntryPoints::TCompleteIslands
&completeIslands
= sep
.getCompleteIslands();
795 _Islands
.reserve(completeIslands
.size());
796 for(uint k
= 0; k
< completeIslands
.size(); ++k
)
799 island
.Name
= completeIslands
[k
].Island
;
800 island
.ContinentName
.clear(); // no access to world map for now ...
801 island
.MinX
= (float) completeIslands
[k
].XMin
;
802 island
.MinY
= (float) completeIslands
[k
].YMin
;
803 island
.MaxX
= (float) completeIslands
[k
].XMax
;
804 island
.MaxY
= (float) completeIslands
[k
].YMax
;
805 // post fix with current season
806 island
.BitmapName
= completeIslands
[k
].Island
+ "_sp.tga";
807 _Islands
.push_back(island
);
810 catch(const NLMISC::EFile
&e
)
817 //============================================================================================================
818 void CGroupMap::updateSelectionAxisSize()
820 if (_SelectionAxisH
->getActive())
822 _SelectionAxisH
->setW(_WReal
);
823 _SelectionAxisH
->setH(1);
824 _SelectionAxisV
->setW(1);
825 _SelectionAxisV
->setH(_HReal
);
829 //============================================================================================================
830 void CGroupMap::setSelectionAxis(bool active
, const NLMISC::CVector2f
&pos
/*=NLMISC::CVector2f::Null*/)
832 _SelectionAxisH
->setActive(active
);
833 _SelectionAxisV
->setActive(active
);
837 worldToWindowSnapped(x
, y
, pos
);
838 _SelectionAxisH
->setX(0);
839 _SelectionAxisH
->setY(y
);
840 _SelectionAxisV
->setX(x
);
841 _SelectionAxisV
->setY(0);
842 updateSelectionAxisSize();
843 _SelectionAxisH
->invalidateCoords();
844 _SelectionAxisV
->invalidateCoords();
848 //============================================================================================================
849 bool CGroupMap::getCtrlsUnder (sint32 x
, sint32 y
, sint32 clipX
, sint32 clipY
, sint32 clipW
, sint32 clipH
, std::vector
<CCtrlBase
*> &vICL
)
851 if (!((x
>= _XReal
) &&
852 (x
< (_XReal
+ _WReal
))&&
854 (y
<= (_YReal
+ _HReal
))))
856 // test against current clip
857 computeCurrentClipContribution(clipX
, clipY
, clipW
, clipH
,
858 clipX
, clipY
, clipW
, clipH
);
861 (x
< (clipX
+ clipW
))&&
863 (y
< (clipY
+ clipH
))))
866 // bool bFound = false;
867 for (uint32 i
= 0; i
< _PolyButtons
.size(); ++i
)
869 if (_PolyButtons
[i
]->contains(CVector2f((float)x
,(float)y
)))
871 vICL
.push_back(_PolyButtons
[i
]);
875 return CInterfaceGroup::getCtrlsUnder(x
, y
, clipX
, clipY
, clipW
, clipH
, vICL
);
878 //============================================================================================================
879 inline void CGroupMap::updateButtonPos(CLandMarkButton
&dest
) const
882 mapToWindowSnapped(x
, y
, dest
.Pos
);
888 //============================================================================================================
889 void CGroupMap::updateCoords()
891 updateSelectionAxisSize();
893 CGroupContainer
*enclosingContainer
= static_cast< CGroupContainer
* >( getEnclosingContainer() );
895 if (!enclosingContainer
|| !enclosingContainer
->getActive()) return;
896 // update position of landmarks
898 // Look if we want to display some details info
899 // Show / Hide details with the ratio indicating the meter per pixel of screen
901 float denomU
= _MapTexW
* _Scale
;
902 _WorldToMapDeltaX
= denomU
!= 0 ? 1.f
/ denomU
: 0.f
;
905 float denomV
= _MapTexH
* _Scale
;
906 _WorldToMapDeltaY
= denomV
!= 0 ? 1.f
/ denomV
: 0.f
;
908 CInterfaceGroup::updateCoords();
910 if (_MapMode
== MapMode_Normal
)
913 float minU
, minV
, maxU
, maxV
;
914 computeUVRect(minU
, minV
, maxU
, maxV
);
915 mapToWorld(_VisibleWorldMin
, CVector2f(minU
,maxV
));
916 mapToWorld(_VisibleWorldMax
, CVector2f(maxU
,minV
));
917 sint32 mapW
= std::min(_MapW
, _WReal
);
918 _MeterPerPixel
= (_VisibleWorldMax
.x
- _VisibleWorldMin
.x
) / mapW
;
919 // bool newLandMarkShown = false;
921 for (i
= 0; i
< _ContinentLM
.size(); ++i
)
923 if (_ContinentLM
[i
]->SearchMatch
)
924 _ContinentLM
[i
]->setActive(true);
926 setupFromZoom(_ContinentLM
[i
], _ContinentLM
[i
]->Type
, _MeterPerPixel
);
928 for (i
= 0; i
< _ContinentText
.size(); ++i
)
930 if (_ContinentText
[i
]->SearchMatch
)
931 _ContinentText
[i
]->setActive(true);
933 setupFromZoom(_ContinentText
[i
], _ContinentText
[i
]->Type
, _MeterPerPixel
);
936 updateLandMarkList(_ContinentLM
);
937 updateLandMarkTextList(_ContinentText
);
938 updateLandMarkList(_UserLM
);
939 updateLandMarkList(_MissionLM
);
941 if (_TargetLM
&& _TargetLM
->getActive()) updateButtonPos(*_TargetLM
);
943 if (_HomeLM
&& _HomeLM
->getActive()) updateButtonPos(*_HomeLM
);
945 updateLandMarkList(_AnimalLM
);
947 updateLandMarkList(_TeammateLM
);
949 for (uint32 i
= 0; i
< _PolyButtons
.size(); ++i
)
950 _PolyButtons
[i
]->updateCoords();
953 updateLandMarkList(_RespawnLM
);
956 for(TDecos::iterator it
= _Decos
.begin(); it
!= _Decos
.end(); ++it
)
958 (*it
)->onUpdate(*this);
961 CInterfaceGroup::updateCoords(); // must update coords twice : first is to get map size and meter per pixel -> this allow to know which landmark are visible
962 //second is to update (possibly newly visible) landmarks position
966 //============================================================================================================
967 void CGroupMap::worldToMap(NLMISC::CVector2f
&dest
,const NLMISC::CVector2f
&src
) const
969 dest
.x
= _MapMinCorner
.x
!= _MapMaxCorner
.x
? (src
.x
- _MapMinCorner
.x
) / (_MapMaxCorner
.x
- _MapMinCorner
.x
) : _MapMinCorner
.x
;
970 dest
.y
= _MapMinCorner
.y
!= _MapMaxCorner
.y
? 1.f
- (src
.y
- _MapMinCorner
.y
) / (_MapMaxCorner
.y
- _MapMinCorner
.y
) : 1.f
- _MapMinCorner
.y
;
973 //============================================================================================================
974 void CGroupMap::mapToWorld(NLMISC::CVector2f
&dest
,const NLMISC::CVector2f
&src
) const
976 dest
.x
= src
.x
* (_MapMaxCorner
.x
- _MapMinCorner
.x
) + _MapMinCorner
.x
;
977 dest
.y
= (1.f
- src
.y
) * (_MapMaxCorner
.y
- _MapMinCorner
.y
) + _MapMinCorner
.y
;
982 //============================================================================================================
983 void CGroupMap::mapToScreen(sint32 &px, sint32 &py, const NLMISC::CVector2f &src) const
985 px = (sint32) (_XReal + (src.x - (_PlayerPos.x + _Offset.x)) * _MapTexW * _Scale);
986 py = (sint32) (_YReal + _HReal - (src.y - (_PlayerPos.y + _Offset.y)) * _MapTexH * _Scale);
989 //============================================================================================================
990 void CGroupMap::mapToWindow(sint32 &px, sint32 &py, const NLMISC::CVector2f &src) const
992 px = (sint32) ((src.x - (_PlayerPos.x + _Offset.x)) * _MapTexW * _Scale);
993 py = (sint32) (_HReal - (src.y - (_PlayerPos.y + _Offset.y)) * _MapTexH * _Scale);
997 //============================================================================================================
998 void CGroupMap::worldToWindow(NLMISC::CVector2f
&dest
, const NLMISC::CVector2f
&src
) const
1000 worldToMap(dest
, src
);
1001 mapToWindow(dest
, dest
);
1004 //============================================================================================================
1005 void CGroupMap::worldToWindowSnapped(sint32
&px
,sint32
&py
, const NLMISC::CVector2f
&src
) const
1007 NLMISC::CVector2f snappedPos
;
1008 snappedPos
.x
= _WorldToMapDeltaX
!= 0.f
? (src
.x
- fmodf(src
.x
, _WorldToMapDeltaX
)) : src
.x
;
1009 snappedPos
.y
= _WorldToMapDeltaY
!= 0.f
? (src
.y
- fmodf(src
.y
, _WorldToMapDeltaY
)) : src
.y
;
1010 worldToMap(snappedPos
, snappedPos
);
1011 mapToWindow(px
, py
, snappedPos
);
1014 //============================================================================================================
1015 void CGroupMap::mapToWindowSnapped(sint32
&px
,sint32
&py
, const NLMISC::CVector2f
&src
) const
1017 NLMISC::CVector2f snappedPos
;
1018 snappedPos
.x
= _WorldToMapDeltaX
!= 0.f
? (src
.x
- fmodf(src
.x
, _WorldToMapDeltaX
)) : src
.x
;
1019 snappedPos
.y
= _WorldToMapDeltaY
!= 0.f
? (src
.y
- fmodf(src
.y
, _WorldToMapDeltaY
)) : src
.y
;
1020 mapToWindow(px
, py
, snappedPos
);
1023 //============================================================================================================
1024 void CGroupMap::mapToScreen(sint32
&px
, sint32
&py
, const NLMISC::CVector2f
&src
) const
1026 px
= (sint32
) (_XReal
+ _MapX
+ (src
.x
- (_PlayerPos
.x
+ _Offset
.x
)) * _MapTexW
* _Scale
);
1027 py
= (sint32
) (_YReal
+ _MapY
+ _HReal
- (src
.y
- (_PlayerPos
.y
+ _Offset
.y
)) * _MapTexH
* _Scale
);
1030 //============================================================================================================
1031 void CGroupMap::windowToScreen(sint32
&destX
, sint32
&destY
, sint32 srcX
, sint32 srcY
) const
1033 destX
= srcX
+ _XReal
;
1034 destY
= srcY
+ _YReal
;
1037 //============================================================================================================
1038 void CGroupMap::mapToWindow(sint32
&px
, sint32
&py
, const NLMISC::CVector2f
&src
) const
1040 px
= (sint32
) ((src
.x
- (_PlayerPos
.x
+ _Offset
.x
)) * _MapTexW
* _Scale
) + _MapX
;
1041 py
= (sint32
) (_HReal
- (src
.y
- (_PlayerPos
.y
+ _Offset
.y
)) * _MapTexH
* _Scale
) + _MapY
;
1044 //============================================================================================================
1045 void CGroupMap::mapToWindow(NLMISC::CVector2f
&dest
,const NLMISC::CVector2f
&src
) const
1047 dest
.x
= ((src
.x
- (_PlayerPos
.x
+ _Offset
.x
)) * _MapTexW
* _Scale
) + (float) _MapX
;
1048 dest
.y
= (sint32
) (_HReal
- (src
.y
- (_PlayerPos
.y
+ _Offset
.y
)) * _MapTexH
* _Scale
) + (float) _MapY
;
1051 //============================================================================================================
1052 void CGroupMap::screenToMap(NLMISC::CVector2f
&dest
, sint32 px
, sint32 py
) const
1054 if (_MapTexW
== 0 || _MapTexH
== 0)
1059 dest
.x
= (px
- (_XReal
+ _MapX
)) / (_MapTexW
* _Scale
) + _PlayerPos
.x
+ _Offset
.x
;
1060 dest
.y
= (_YReal
+ _HReal
+ _MapY
- py
) / (_MapTexH
* _Scale
) + _PlayerPos
.y
+ _Offset
.y
;
1063 //============================================================================================================
1064 void CGroupMap::windowToMap(NLMISC::CVector2f
&dest
,sint32 px
,sint32 py
) const
1066 if (_MapTexW
== 0 || _MapTexH
== 0)
1071 dest
.x
= ((px
+ 0.5f
) - _MapX
) / (_MapTexW
* _Scale
) + _PlayerPos
.x
+ _Offset
.x
;
1072 dest
.y
= (_HReal
+ _MapY
- (py
- 0.5f
)) / (_MapTexH
* _Scale
) + _PlayerPos
.y
+ _Offset
.y
;
1075 //============================================================================================================
1076 void CGroupMap::updateLMPosFromDBPos(CLandMarkButton
*dest
,sint32 px
, sint32 py
)
1079 if (px
== 0 && py
== 0)
1081 dest
->setActive(false);
1085 NLMISC::CVector2f
worldPos(px
* 0.001f
, py
* 0.001f
);
1086 NLMISC::CVector2f mapPos
;
1087 worldToMap(mapPos
, worldPos
);
1088 if (mapPos
.x
!= dest
->Pos
.x
)
1090 dest
->Pos
.x
= mapPos
.x
;
1091 dest
->invalidateCoords();
1093 if (mapPos
.y
!= dest
->Pos
.y
)
1095 dest
->Pos
.y
= mapPos
.y
;
1096 dest
->invalidateCoords();
1098 dest
->setActive(true);
1101 //============================================================================================================
1102 // create mission position state object from base db path
1103 static CSmartPtr
<CNamedEntityPositionState
> buildMissionPositionState(CInterfaceManager
*im
, const std::string
&baseDBpath
, uint missionIndex
, uint targetIndex
)
1106 CCDBNodeLeaf
*name
= NLGUI::CDBManager::getInstance()->getDbProp(baseDBpath
+ NLMISC::toString(":%d:TARGET%d:TITLE", (int) missionIndex
, (int) targetIndex
));
1107 CCDBNodeLeaf
*x
= NLGUI::CDBManager::getInstance()->getDbProp(baseDBpath
+ NLMISC::toString(":%d:TARGET%d:X", (int) missionIndex
, (int) targetIndex
));
1108 CCDBNodeLeaf
*y
= NLGUI::CDBManager::getInstance()->getDbProp(baseDBpath
+NLMISC::toString(":%d:TARGET%d:Y", (int) missionIndex
, (int) targetIndex
));
1109 CSmartPtr
<CNamedEntityPositionState
> ps
= new CNamedEntityPositionState
;
1110 ps
->build(name
, x
, y
);
1114 //============================================================================================================
1115 void CGroupMap::checkCoords()
1117 if (!_Active
) return;
1119 if (!_MapTF
&& !_MapLoadFailure
)
1124 updateContinentInfo();
1126 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1128 // **** update landmark for missions from the database
1129 if (_MissionPosStates
.empty()) // pointers on db node initialised ?
1131 _MissionPosStates
.resize(2 * MAX_NUM_MISSIONS
* MAX_NUM_MISSION_TARGETS
); // 2 is because of group missions
1132 uint targetIndex
= 0;
1133 for(uint k
= 0; k
< MAX_NUM_MISSIONS
; ++k
)
1135 for(uint l
= 0; l
<MAX_NUM_MISSION_TARGETS
; ++l
)
1137 _MissionPosStates
[targetIndex
++] = buildMissionPositionState(pIM
, MISSIONS_DB_PATH
, k
, l
);
1138 _MissionPosStates
[targetIndex
++] = buildMissionPositionState(pIM
, GROUP_MISSIONS_DB_PATH
, k
, l
);
1141 // also fill ptr for special landmarks (target, home & respawn)
1142 _TargetPos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":TARGET");
1143 _HomePos
= NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":HOME_POINT");
1146 // bool mustInvalidateCoords = false;
1147 for(uint k
= 0; k
< 2 * MAX_NUM_MISSIONS
* MAX_NUM_MISSION_TARGETS
; ++k
)
1149 sint32 nameID
= _MissionPosStates
[k
]->getNameNode()->getValue32();
1150 if (nameID
!= _MissionTargetTextIDs
[k
])
1152 _MissionTargetTextIDs
[k
] = nameID
;
1153 if (_MissionTargetTextIDs
[k
] == 0)
1155 if (_MissionLM
[k
] != NULL
)
1157 delCtrl(_MissionLM
[k
]);
1158 _MissionLM
[k
] = NULL
;
1163 // create a new button if necessary
1164 if (_MissionLM
[k
] == NULL
)
1166 _MissionLM
[k
] = createLandMarkButton(_MissionLMOptions
);
1167 _MissionLM
[k
]->setParent(this);
1168 addCtrl(_MissionLM
[k
]);
1171 // text must be received
1172 _MissionTargetTextReceived
[k
] = false;
1176 // update text if needed
1177 if (!_MissionTargetTextReceived
[k
])
1180 if (STRING_MANAGER::CStringManagerClient::instance()->getDynString(_MissionTargetTextIDs
[k
], result
))
1182 _MissionLM
[k
]->setDefaultContextHelp(result
);
1183 _MissionTargetTextReceived
[k
] = true;
1189 // **** retrieve pos of target and update it, or hide it if there's no target
1192 sint32 px
= (sint32
) (_TargetPos
->getValue64() >> 32);
1193 sint32 py
= _TargetPos
->getValue32();
1194 updateLMPosFromDBPos(_TargetLM
, px
, py
);
1195 if (_TargetLM
->getActive())
1199 if (UserEntity
->selection() != CLFECOMMON::INVALID_SLOT
&& UserEntity
->selection() != 0)
1201 CEntityCL
*sel
= EntitiesMngr
.entity(UserEntity
->selection());
1204 _TargetLM
->setDefaultContextHelp(NLMISC::CI18N::get("uiTargetTwoPoint") + sel
->removeTitleAndShardFromName(sel
->getEntityName()));
1211 // **** retrieve pos of home and update it, or hide it if there's no target
1214 sint32 px
= (sint32
) (_HomePos
->getValue64() >> 32);
1215 sint32 py
= _HomePos
->getValue32();
1216 updateLMPosFromDBPos(_HomeLM
, px
, py
);
1219 // **** retrieve pos of respawn and update it, or hide it if there's no target
1223 if (!_ArkPoints
.empty())
1225 offset
= _ArkPoints
.size();
1226 if (_ArkPoints
.size() < _RespawnLM
.size())
1228 for (i
= (uint
)_ArkPoints
.size(); i
< _RespawnLM
.size(); i
++)
1230 delCtrl(_RespawnLM
[i
]);
1231 _RespawnLM
[i
] = NULL
;
1235 _RespawnLM
.resize(_ArkPoints
.size(), NULL
);
1236 for(i
= 0; i
< _ArkPoints
.size(); i
++)
1238 if (_RespawnLM
[i
] == NULL
)
1240 _RespawnLM
[i
] = createArkPointButton(_ArkPoints
[i
]);
1241 _RespawnLM
[i
]->setId(this->getId() + ":arklm_" + NLMISC::toString(i
));
1242 _RespawnLM
[i
]->setParent(this);
1243 _RespawnLM
[i
]->setDefaultContextHelp(_ArkPoints
[i
].Title
);
1244 _RespawnLM
[i
]->HandleEvents
= true;
1245 addCtrl(_RespawnLM
[i
]);
1246 updateLMPosFromDBPos(_RespawnLM
[i
], _ArkPoints
[i
].x
, _ArkPoints
[i
].y
);
1252 if (_ArkPoints
.empty() || !isIsland())
1254 if (offset
+ _RespawnPos
.size() < _RespawnLM
.size())
1256 for (i
= offset
+ _RespawnPos
.size(); i
< _RespawnLM
.size(); i
++)
1258 delCtrl(_RespawnLM
[i
]);
1259 _RespawnLM
[i
] = NULL
;
1263 _RespawnLM
.resize(offset
+ _RespawnPos
.size(), NULL
);
1264 for(int j
= 0; j
< _RespawnPos
.size(); ++j
)
1267 if (_RespawnLM
[i
] == NULL
)
1269 _RespawnLM
[i
] = createLandMarkButton(_RespawnLMOptions
);
1270 _RespawnLM
[i
]->setId(this->getId() + ":rplm_" + NLMISC::toString(i
));
1271 _RespawnLM
[i
]->setParent(this);
1272 if (_MapMode
== MapMode_SpawnSquad
)
1273 _RespawnLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get("uiSquadSpawnPoint") + NLMISC::toString(" %u", i
+1));
1278 _RespawnLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get("uiR2EntryPoint"));
1282 _RespawnLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get("uiRespawnPoint"));
1284 _RespawnLM
[i
]->HandleEvents
= R2::getEditor().getMode() != R2::CEditor::EditionMode
;
1286 addCtrl(_RespawnLM
[i
]);
1289 updateLMPosFromDBPos(_RespawnLM
[i
], _RespawnPos
[j
].x
, _RespawnPos
[j
].y
);
1294 if ((_MapMode
== MapMode_Death
) || (_MapMode
== MapMode_SpawnSquad
))
1296 if (_RespawnPosReseted
)
1298 _RespawnPosReseted
= false;
1300 _RespawnSelected
= 0;
1301 if (_MapMode
== MapMode_Death
)
1302 NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RESPAWN_PT")->setValue32(_RespawnSelected
);
1303 else if (_MapMode
== MapMode_SpawnSquad
)
1304 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:SQUAD_RESPAWN_PT")->setValue32(_RespawnSelected
);
1305 if (!_RespawnLM
.empty())
1306 _RespawnSelectedBitmap
->setParentPos(_RespawnLM
[_RespawnSelected
]);
1310 _RespawnSelected
= getRespawnSelected();
1311 if (!_RespawnLM
.empty())
1312 _RespawnSelectedBitmap
->setParentPos(_RespawnLM
[_RespawnSelected
]);
1316 // **** Animal Landmarks
1317 // initialize DB if not done
1318 if(_AnimalPosStates
.empty() && !_AnimalLM
.empty())
1320 _AnimalPosStates
.resize(_AnimalLM
.size());
1322 nlassert(_AnimalPosStates
.size()<=MAX_INVENTORY_ANIMAL
);
1323 for(uint i
=0;i
<MAX_INVENTORY_ANIMAL
;i
++)
1325 _AnimalPosStates
[i
] = new CAnimalPositionState
;
1326 _AnimalPosStates
[i
]->build(NLMISC::toString("SERVER:PACK_ANIMAL:BEAST%d",i
));
1329 // update DB pos & tooltip text
1330 for(i
=0;i
<_AnimalLM
.size();i
++)
1336 _AnimalPosStates
[i
]->getPos(px
, py
);
1337 updateLMPosFromDBPos(_AnimalLM
[i
], px
, py
);
1341 _AnimalLM
[i
]->setActive(false);
1343 else if (_AnimalLM
[i
]->getActive())
1345 // update texture from animal status
1346 CCDBNodeLeaf
*statusNode
= NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d", i
) + ":STATUS", false);
1347 if (statusNode
&& ANIMAL_STATUS::isInStable((ANIMAL_STATUS::EAnimalStatus
)statusNode
->getValue32()) )
1349 _AnimalLM
[i
]->setTexture(_AnimalStableLMOptions
.LandMarkTexNormal
);
1350 _AnimalLM
[i
]->setScale(true); // hardcoded because chosen icon is too big (bad...)
1353 if (statusNode
&& ANIMAL_STATUS::isDead((ANIMAL_STATUS::EAnimalStatus
)statusNode
->getValue32()) )
1355 _AnimalLM
[i
]->setTexture(_AnimalDeadLMOptions
.LandMarkTexNormal
);
1356 _AnimalLM
[i
]->setScale(true); // hardcoded because chosen icon is too big (bad...)
1360 _AnimalLM
[i
]->setTexture(_AnimalLMOptions
.LandMarkTexNormal
);
1363 // update tooltip text
1364 ANIMAL_TYPE::EAnimalType at
;
1365 at
= (ANIMAL_TYPE::EAnimalType
)NLGUI::CDBManager::getInstance()->getDbProp("SERVER:PACK_ANIMAL:BEAST"+toString(i
)+":TYPE")->getValue32();
1370 case ANIMAL_TYPE::All
: sPrefix
= "uiPATitleMount"; break;
1371 case ANIMAL_TYPE::Mount
: sPrefix
= "uiPATitleMount"; break;
1372 case ANIMAL_TYPE::Packer
: sPrefix
= "uiPATitlePacker"; break;
1373 case ANIMAL_TYPE::Demon
: sPrefix
= "uiPATitleDemon"; break;
1375 _AnimalLM
[i
]->setDefaultContextHelp(NLMISC::CI18N::get(sPrefix
+toString(i
+1)));
1380 // **** Teammate Landmarks
1381 // initialize DB if not done
1382 if(_TeammatePosStates
.empty() && !_TeammateLM
.empty())
1384 _TeammatePosStates
.resize(MaxNumPeopleInTeam
);
1385 for(uint i
=0; i
< MaxNumPeopleInTeam
; i
++)
1387 _TeammatePosStates
[i
] = new CTeammatePositionState
;
1388 _TeammatePosStates
[i
]->build(NLMISC::toString("SERVER:GROUP:%d",i
));
1392 for(i
=0; i
< _TeammateLM
.size(); i
++)
1399 if (_TeammatePosStates
[i
]->getPos(px
, py
))
1401 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1402 uint32 val
= NLGUI::CDBManager::getInstance()->getDbProp(NLMISC::toString("SERVER:GROUP:%d:NAME",i
))->getValue32();
1403 STRING_MANAGER::CStringManagerClient
*pSMC
= STRING_MANAGER::CStringManagerClient::instance();
1406 if (pSMC
->getString(val
, res
))
1408 std::string res2
= CEntityCL::removeTitleAndShardFromName(res
);
1409 _TeammateLM
[i
]->setDefaultContextHelp(res2
);
1412 updateLMPosFromDBPos(_TeammateLM
[i
], px
, py
);
1416 // update position for mission landmarks
1417 // TODO : try to factor behaviour between anim / treamate / missions (they are all dynamic)
1418 // TODO : make just one list of landmark with a CCompassTarget would be better ?
1419 for(i
=0; i
< _MissionPosStates
.size(); i
++)
1424 if (_MissionPosStates
[i
]->getPos(px
, py
))
1426 updateLMPosFromDBPos(_MissionLM
[i
], px
, py
);
1432 // **** check if player has moved
1433 if (!EntitiesMngr
.entities().empty())
1435 if (EntitiesMngr
.entity(0))
1437 const NLMISC::CVectorD
&playerPos
= EntitiesMngr
.entity(0)->pos();
1438 CVector2f
newPlayerPos((float) playerPos
.x
, (float) playerPos
.y
);
1439 if (newPlayerPos
!= _OldPlayerPos
)
1441 _OldPlayerPos
= newPlayerPos
;
1446 CInterfaceGroup::checkCoords();
1449 //============================================================================================================
1450 static void setupFromZoom(CViewBase
*pVB
, CContLandMark::TContLMType t
, float fMeterPerPixel
)
1452 bool active
= false;
1454 if ((t
== CContLandMark::Capital
) && (fMeterPerPixel
<= 5.0f
)) active
= true;
1455 if ((t
== CContLandMark::Village
) && (fMeterPerPixel
<= 4.0f
)) active
= true;
1456 if ((t
== CContLandMark::Outpost
) && (fMeterPerPixel
<= 4.0f
)) active
= true;
1457 if ((t
== CContLandMark::Stable
) && (fMeterPerPixel
<= 3.5f
)) active
= true;
1459 if ((t
== CContLandMark::Region
) && (fMeterPerPixel
<= 50.0f
)) active
= true;
1460 if ((t
== CContLandMark::Place
) && (fMeterPerPixel
<= 6.0f
)) active
= true;
1461 if ((t
== CContLandMark::Street
) && (fMeterPerPixel
<= 2.0f
)) active
= true;
1462 if (t
== CContLandMark::Unknown
) active
= true;
1463 pVB
->setActive(active
);
1467 //============================================================================================================
1468 void CGroupMap::computeUVRect(float &minU
, float &minV
, float &maxU
, float &maxV
) const
1470 minU
= _Offset
.x
+ _PlayerPos
.x
;
1471 minV
= _Offset
.y
+ _PlayerPos
.y
;
1472 // delta U & V for a pixel on screen
1473 float deltaU
= 1.f
/ favoid0(_MapTexW
* _Scale
);
1474 float deltaV
= 1.f
/ favoid0(_MapTexH
* _Scale
);
1478 minU
-= deltaU
* _MapX
;
1483 minV
+= deltaV
* _MapY
;
1485 // ensure that UV displacement results in moves pixel by pixel on screen (landmarks move pixel by pixel, so the map may appear not to follow them because it moves smoothly)
1486 minU
-= fmodf(minU
, deltaU
);
1487 minV
-= fmodf(minV
, deltaV
);
1489 sint32 mapW
= std::min(_MapW
, _WReal
);
1490 sint32 mapH
= std::min(_MapH
, _HReal
);
1492 maxU
= minU
+ ((float) mapW
/ favoid0(_Scale
* (float) _MapTexW
));
1493 maxV
= minV
+ ((float) mapH
/ favoid0(_Scale
* (float) _MapTexH
));
1497 //============================================================================================================
1498 void CGroupMap::computeFrustumQuad(CQuad
&fruQuad
) const
1502 const NLMISC::CVector
&camPos
= MainCam
.getMatrix().getPos();
1503 worldToWindow(winPos
, camPos
);
1504 fruQuad
.V0
.set(winPos
.x
, winPos
.y
, 0.f
);
1505 CVector projectedFront
= MainCam
.getMatrix().getJ();
1506 projectedFront
.z
= 0.f
;
1507 if (projectedFront
.norm() <= 0.01f
)
1509 projectedFront
= MainCam
.getMatrix().getK();
1510 projectedFront
.z
= 0.f
;
1512 CVector front
= projectedFront
.normed();
1513 CVector
right(- front
.y
, front
.x
, 0.f
);
1514 const NL3D::CFrustum
&fru
= MainCam
.getFrustum();
1515 float farRight
= fru
.Right
* (fru
.Far
/ fru
.Near
);
1516 float farLeft
= fru
.Left
* (fru
.Far
/ fru
.Near
);
1517 worldToWindow(winPos
, camPos
+ farRight
* right
+ fru
.Far
* front
);;
1518 fruQuad
.V1
.set(winPos
.x
, winPos
.y
, 0.f
);
1519 worldToWindow(winPos
, camPos
+ farLeft
* right
+ fru
.Far
* front
);;
1520 fruQuad
.V3
.set(winPos
.x
, winPos
.y
, 0.f
);
1521 CVector middle
= 0.5f
* (fruQuad
.V1
+ fruQuad
.V3
);
1522 fruQuad
.V2
= fruQuad
.V0
+ 2.f
* (middle
- fruQuad
.V0
);
1525 //============================================================================================================
1526 void CGroupMap::draw()
1529 for(TDecos::iterator it
= _Decos
.begin(); it
!= _Decos
.end(); ++it
)
1531 (*it
)->onPreRender(*this);
1533 // TMP TMP for debug
1534 static volatile bool clearAll
= false;
1537 removeLandMarks(_ContinentLM
);
1538 removeLandMarks(_MissionLM
);
1539 removeLandMarks(_AnimalLM
);
1540 removeLandMarks(_TeammateLM
);
1541 for (uint k
= 0; k
< _ContinentText
.size(); ++k
)
1542 delView(_ContinentText
[k
]);
1543 _ContinentText
.clear();
1544 for (uint k
= 0; k
< _PolyButtons
.size(); ++k
)
1545 delCtrl(_PolyButtons
[k
]);
1546 _PolyButtons
.clear();
1549 sint32 oldSciX
, oldSciY
, oldSciW
, oldSciH
;
1550 makeNewClip (oldSciX
, oldSciY
, oldSciW
, oldSciH
);
1551 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1552 CViewRenderer
&vr
= *CViewRenderer::getInstance();
1553 uint8 alpha
= CWidgetManager::getInstance()->getGlobalColorForContent().A
;
1556 // No Op if screen minimized
1557 if(vr
.isMinimized())
1562 vr
.getScreenSize(sw
, sh
);
1564 NL3D::CScissor oldScissor
;
1565 oldScissor
= Driver
->getScissor();
1566 sint32 sciX
, sciY
, sciW
, sciH
;
1567 vr
.getClipWindow(sciX
, sciY
, sciW
, sciH
);
1568 NL3D::CScissor newScissor
;
1569 newScissor
.X
= sciX
/ (float) sw
;
1570 newScissor
.Width
= sciW
/ (float) sw
;
1571 newScissor
.Y
= sciY
/ (float) sh
;
1572 newScissor
.Height
= sciH
/ (float) sh
;
1574 if (!_PlayerPosTF
&& !_PlayerPosLoadFailure
)
1578 if (!_MapLoadFailure
)
1580 if (_MapTexW
!= 0 && _MapTexH
!= 0)
1582 float minU
, minV
, maxU
, maxV
;
1583 computeUVRect(minU
, minV
, maxU
, maxV
);
1585 sint32 mapW
= std::min(_MapW
, _WReal
);
1586 sint32 mapH
= std::min(_MapH
, _HReal
);
1587 // Display fog of war map
1588 CVector2f
fowMin(0,0), fowMax(0,0);
1589 float fowURatio
= 0.0f
;
1590 float fowVRatio
= 0.0f
;
1591 // Convert u,v (from map coords) to world coordinates
1592 CVector2f worldMin
, worldMax
;
1593 mapToWorld(worldMin
, CVector2f(minU
,minV
));
1594 mapToWorld(worldMax
, CVector2f(maxU
,maxV
));
1596 if (_CurContinent
!= NULL
)
1598 // Convert world coordinate to map coordinate in the fog of war map
1599 CFogOfWar
&rFOW
= _CurContinent
->FoW
;
1600 if (rFOW
.getMaxX() != rFOW
.getMinX()) fowMin
.x
= (worldMin
.x
- rFOW
.getMinX()) / (rFOW
.getMaxX() - rFOW
.getMinX());
1601 if (rFOW
.getMaxY() != rFOW
.getMinY()) fowMin
.y
= (worldMin
.y
- rFOW
.getMinY()) / (rFOW
.getMaxY() - rFOW
.getMinY());
1602 if (rFOW
.getMaxX() != rFOW
.getMinX()) fowMax
.x
= (worldMax
.x
- rFOW
.getMinX()) / (rFOW
.getMaxX() - rFOW
.getMinX());
1603 if (rFOW
.getMaxY() != rFOW
.getMinY()) fowMax
.y
= (worldMax
.y
- rFOW
.getMinY()) / (rFOW
.getMaxY() - rFOW
.getMinY());
1604 if ((fowMin
.x
>= 0) && (fowMin
.x
<= 1) &&
1605 (fowMin
.y
>= 0) && (fowMin
.y
<= 1) &&
1606 (fowMax
.x
>= 0) && (fowMax
.x
<= 1) &&
1607 (fowMax
.y
>= 0) && (fowMax
.y
<= 1))
1609 fowURatio
= (float)rFOW
.getMapWidth() / favoid0((float)rFOW
.getRealWidth());
1610 fowVRatio
= (float)rFOW
.getMapHeight() / favoid0((float)rFOW
.getRealHeight());
1615 vr
.drawCustom(_XReal
+ std::max(_MapX
, (sint32
) 0), _YReal
- std::min(_MapY
, (sint32
) 0), mapW
, mapH
,
1616 CUV(minU
* _URatio
, minV
* _VRatio
), CUV(maxU
* _URatio
, maxV
* _VRatio
),
1617 CUV(fowMin
.x
* fowURatio
, fowMin
.y
* fowVRatio
), CUV(fowMax
.x
* fowURatio
, fowMax
.y
* fowVRatio
),
1618 CRGBA(255, 255, 255, alpha
),
1621 // Look if we want to display some details info
1622 // Show / Hide details with the ratio indicating the meter per pixel of screen
1625 float fMeterPerPixel = (worldMax.x - worldMin.x) / mapW;
1628 for (i = 0; i < _ContinentLM.size(); ++i)
1629 setupFromZoom(_ContinentLM[i], _ContinentLM[i]->Type, fMeterPerPixel);
1630 for (i = 0; i < _ContinentText.size(); ++i)
1631 setupFromZoom(_ContinentText[i], _ContinentText[i]->Type, fMeterPerPixel);
1636 /* if (_MapW < _WReal || _MapH < _HReal)
1637 vr.drawWiredQuad(_XReal + _MapX, _YReal - _MapY, _MapW, _MapH, CRGBA(0, 0, 0, alpha));*/
1641 // if editor is in edition mode, draw the frustum instead (for better visibility)
1645 CRGBA
fruColor(0, 0, 0);
1649 if (getArkPowoMode() == "editor" || R2::getEditor().getMode() == R2::CEditor::EditionMode
)
1651 static volatile bool wantFrustum
= true;
1654 computeFrustumQuad(fruQuad
);
1655 _FrustumView
->setActive(true);
1656 //_FrustumView->setAdditif(true);
1657 _FrustumView
->setQuad(fruQuad
);
1658 _FrustumView
->updateCoords();
1659 // handle mouse over
1660 if (CWidgetManager::getInstance()->getPointer())
1662 sint32 originX
, originY
;
1663 getCorner(originX
, originY
, getPosRef());
1664 CVector
delta((float) originX
, (float) originY
, 0.f
);
1665 fruTri
= CTriangle(fruQuad
.V0
, fruQuad
.V1
, fruQuad
.V2
);
1666 CVector
mousePos((float) CWidgetManager::getInstance()->getPointer()->getXReal(), (float) CWidgetManager::getInstance()->getPointer()->getYReal(), 0.f
);
1669 float deltaBlend
= DT
/ (0.001f
* (float) _FrustumViewBlendTimeInMs
);
1670 bool hit
= fruTri
.intersect(mousePos
+ CVector::K
, mousePos
- CVector::K
, dummyHit
, CPlane(0.f
, 0.f
, 0.f
, 1.f
));
1671 NLMISC::incrementalBlend(_FrustumOverBlendFactor
, hit
? 1.f
: 0.f
, deltaBlend
);
1672 fruColor
.blendFromui(_FrustumViewColor
, _FrustumViewColorOver
, (uint8
) (255 * _FrustumOverBlendFactor
));
1676 fruColor
= _FrustumViewColor
;
1679 _FrustumView
->setColorRGBA(fruColor
);
1684 _FrustumView
->setActive(false);
1688 //Driver->setScissor(oldScissor);
1689 // let parent view draw continent, mission and user locations
1690 CInterfaceGroup::draw();
1695 Driver
->setScissor(newScissor
);
1697 if (getArkPowoMode() == "editor" || R2::getEditor().getMode() != R2::CEditor::EditionMode
)
1699 // Draw the player TODO : replace with a CViewQuad
1700 if (!_PlayerPosLoadFailure
)
1702 // draw rotated bitmap for player position
1703 const NLMISC::CVector
&front3f
= UserEntity
->front();
1704 NLMISC::CVector2f front
;
1705 NLMISC::CVector2f right
;
1706 front
.set(front3f
.x
, front3f
.y
);
1707 right
.set(front3f
.y
, - front3f
.x
);
1710 mapToScreen(spx
, spy
, _PlayerPos
);
1711 NLMISC::CVector center
;
1712 center
.set((float) spx
, (float) spy
, 0.f
);
1713 NLMISC::CQuadColorUV quv
;
1714 quv
.V0
= center
- 0.5f
* (float) _PlayerPosTexW
* right
- 0.5f
* (float) _PlayerPosTexH
* front
;
1715 quv
.V1
= center
+ 0.5f
* (float) _PlayerPosTexW
* right
- 0.5f
* (float) _PlayerPosTexH
* front
;
1716 quv
.V2
= center
+ 0.5f
* (float) _PlayerPosTexW
* right
+ 0.5f
* (float) _PlayerPosTexH
* front
;
1717 quv
.V3
= center
- 0.5f
* (float) _PlayerPosTexW
* right
+ 0.5f
* (float) _PlayerPosTexH
* front
;
1718 quv
.Uv0
.set(0.f
, 1.f
);
1719 quv
.Uv1
.set(1.f
, 1.f
);
1720 quv
.Uv2
.set(1.f
, 0.f
);
1721 quv
.Uv3
.set(0.f
, 0.f
);
1722 quv
.Color0
= quv
.Color1
= quv
.Color2
= quv
.Color3
= CRGBA(255, 255, 255, alpha
);
1723 quv
.V0
.x
/= (float) sw
;
1724 quv
.V0
.y
/= (float) sh
;
1725 quv
.V1
.x
/= (float) sw
;
1726 quv
.V1
.y
/= (float) sh
;
1727 quv
.V2
.x
/= (float) sw
;
1728 quv
.V2
.y
/= (float) sh
;
1729 quv
.V3
.x
/= (float) sw
;
1730 quv
.V3
.y
/= (float) sh
;
1731 Driver
->drawQuads(&quv
, 1, _PlayerPosMaterial
);
1735 // draw border of frustum
1738 if (getArkPowoMode() == "editor" || R2::getEditor().getMode() == R2::CEditor::EditionMode
)
1740 if (_FrustumMaterial
.empty())
1742 // create material for the world map
1743 _FrustumMaterial
= Driver
->createMaterial();
1744 if (!_FrustumMaterial
.empty())
1746 _FrustumMaterial
.initUnlit();
1747 _FrustumMaterial
.setZWrite(false);
1748 _FrustumMaterial
.setZFunc(NL3D::UMaterial::always
);
1749 _FrustumMaterial
.setBlend (true);
1750 _FrustumMaterial
.setBlendFunc (NL3D::UMaterial::srcalpha
, NL3D::UMaterial::invsrcalpha
);
1751 _FrustumMaterial
.setDoubleSided();
1754 if (!_FrustumMaterial
.empty())
1757 _FrustumMaterial
.setColor(fruColor
);
1758 //Driver->setScissor(newScissor);
1759 NL3D::UDriver::TPolygonMode oldPolygonMode
= Driver
->getPolygonMode();
1760 Driver
->setPolygonMode(NL3D::UDriver::Line
);
1763 fruTri
.V0
.set((fruQuad
.V0
.x
+ _XReal
) / sw
, (fruQuad
.V0
.y
+ _YReal
) / sh
, 0.f
);
1764 fruTri
.V1
.set((fruQuad
.V1
.x
+ _XReal
) / sw
, (fruQuad
.V1
.y
+ _YReal
) / sh
, 0.f
);
1765 fruTri
.V2
.set((fruQuad
.V3
.x
+ _XReal
) / sw
, (fruQuad
.V3
.y
+ _YReal
) / sh
, 0.f
);
1766 Driver
->drawTriangle(fruTri
, _FrustumMaterial
);
1767 Driver
->setPolygonMode(oldPolygonMode
);
1772 // Draw all poly buttons
1773 for (uint32 i
= 0; i
< _PolyButtons
.size(); ++i
)
1775 _PolyButtons
[i
]->drawPolyButton();
1778 // Restore Old Scissor
1779 Driver
->setScissor(oldScissor
);
1781 restoreClip (oldSciX
, oldSciY
, oldSciW
, oldSciH
);
1784 //============================================================================================================
1785 bool CGroupMap::handleEvent(const NLGUI::CEventDescriptor
&event
)
1787 CInterfaceManager
*im
= CInterfaceManager::getInstance();
1788 // if R2 editor editor is on, give it a chance to handle the event first
1789 if (ClientCfg
.R2EDEnabled
&& R2::getEditor().getCurrentTool())
1791 bool handled
= false;
1792 bool panEnd
= false;
1793 // handle standard clicks
1794 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
1796 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
1797 panEnd
= eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
&& _Panning
&& _HasMoved
;
1798 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
&& !panEnd
)
1800 //if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
1801 // NB : don't test capture of mouse here, because
1802 // some R2 tool may begin outside of this window
1803 // example : clicking in the palette window and doing a drag-and-drop to the
1806 handled
= R2::getEditor().getCurrentTool()->onMouseLeftButtonUp();
1809 handled
= R2::getEditor().getCurrentTool()->onMouseLeftButtonClicked();
1812 if (!handled
&& R2::getEditor().getMode() == R2::CEditor::EditionMode
)
1814 if (R2::getEditor().getCurrentTool())
1816 if (!R2::getEditor().getCurrentTool()->getPreviousToolClickEndFlag())
1818 if (CWidgetManager::getInstance()->getCapturePointerLeft() == this)
1820 // unselected unless tool has been changed before last mouse left up (happens when one's finish a route using double click -> should not unselect then)
1821 R2::getEditor().setSelectedInstance(NULL
);
1827 else if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup
)
1829 if (CWidgetManager::getInstance()->getCapturePointerRight() == this)
1831 if (isIn(eventDesc
.getX(), eventDesc
.getY()))
1833 NLMISC::CVector2f clickPos
;
1834 screenToMap(clickPos
, eventDesc
.getX(), eventDesc
.getY());
1835 if (clickPos
.x
>= 0.f
&&
1836 clickPos
.y
>= 0.f
&&
1837 clickPos
.x
<= 1.f
&&
1841 handled
= R2::getEditor().getCurrentTool()->onMouseRightButtonClicked();
1849 handled
= handled
|| R2::getEditor().getCurrentTool()->handleEvent(event
);
1860 for (uint32 i
= 0; i
< _PolyButtons
.size(); ++i
)
1861 if (_PolyButtons
[i
]->handleEvent(event
))
1864 // left button can be used to 'pan' the map
1865 // mouse wheel can be used to zoom in/out
1866 if (event
.getType() == NLGUI::CEventDescriptor::mouse
)
1870 const NLGUI::CEventDescriptorMouse
&eventDesc
= (const NLGUI::CEventDescriptorMouse
&)event
;
1872 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftup
)
1874 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this)
1883 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightdown
)
1885 CWidgetManager::getInstance()->setCapturePointerRight(this);
1889 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouseleftdown
)
1891 if (isIn(eventDesc
.getX(), eventDesc
.getY()))
1893 CWidgetManager::getInstance()->setCapturePointerLeft(this);
1894 _StartXForPaning
= eventDesc
.getX();
1895 _StartYForPaning
= eventDesc
.getY();
1896 _StartWorldOffsetForPaning
= _WorldOffset
;
1898 // Clamp the start WorldOffset on the Move start. NB: not clamped on a scale
1900 _StartWorldOffsetForPaning
.x
= _Offset
.x
* (_MapMaxCorner
.x
- _MapMinCorner
.x
);
1901 _StartWorldOffsetForPaning
.y
= _Offset
.y
* (_MapMaxCorner
.y
- _MapMinCorner
.y
);
1903 _PanStartDateInMs
= T1
;
1904 /** If in editor, and current tool is a creation tool, only handle panning after a small delta pos / delta time
1905 * for better ergonomy
1907 if (ClientCfg
.R2EDEnabled
&& R2::getEditor().getCurrentTool() &&
1908 R2::getEditor().getCurrentTool()->isCreationTool()
1911 _DeltaPosBeforePan
= 2;
1912 _DeltaTimeBeforePanInMs
= 300;
1916 // handle panning immediately
1917 _DeltaPosBeforePan
= 0;
1918 _DeltaTimeBeforePanInMs
= 0;
1925 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousemove
)
1927 if (CWidgetManager::getInstance()->getCapturePointerLeft() != this || !_Panning
)
1928 return CInterfaceGroup::handleEvent(event
);
1930 if (_MapTexW
!= 0 && _MapTexH
!= 0)
1932 if (_HasMoved
|| (T1
- _PanStartDateInMs
) > _DeltaTimeBeforePanInMs
||
1933 (uint
) abs(eventDesc
.getX() - _StartXForPaning
) > _DeltaPosBeforePan
||
1934 (uint
) abs(eventDesc
.getY() - _StartYForPaning
) > _DeltaPosBeforePan
)
1937 NLMISC::CVector2f dWorld
;
1938 dWorld
.x
= - (_MapMaxCorner
.x
- _MapMinCorner
.x
) * (eventDesc
.getX() - _StartXForPaning
) / (_MapTexW
* _Scale
);
1939 dWorld
.y
= + (_MapMaxCorner
.y
- _MapMinCorner
.y
) * (eventDesc
.getY() - _StartYForPaning
) / (_MapTexH
* _Scale
);
1940 _WorldOffset
= _StartWorldOffsetForPaning
+ dWorld
;
1942 // Clamp the WorldOffset on a Move. NB: not clamped on a scale
1944 _WorldOffset
.x
= _Offset
.x
* (_MapMaxCorner
.x
- _MapMinCorner
.x
);
1945 _WorldOffset
.y
= _Offset
.y
* (_MapMaxCorner
.y
- _MapMinCorner
.y
);
1955 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mousewheel
&& !_Panning
)
1957 sint32 wheel
= eventDesc
.getWheel();
1958 float newScale
= _UserScale
;
1974 float realScale
= computeRealScaleFromUserScale(newScale
);
1975 if (realScale
> getActualMaxScale())
1977 newScale
= computeUserScaleFromRealScale(getActualMaxScale());
1983 NLMISC::CVector2f mapPos
;
1984 screenToMap(mapPos
, eventDesc
.getX(), eventDesc
.getY());
1985 setScale(newScale
, mapPos
);
1989 if (eventDesc
.getEventTypeExtended() == NLGUI::CEventDescriptorMouse::mouserightup
)
1991 // convert click pos into map pos
1992 if (_MapTexW
== 0 || _MapTexH
== 0)
1994 _RightClickLastPos
.set(0.f
, 0.f
);
1998 NLMISC::CVector2f clickPos
;
1999 screenToMap(clickPos
, eventDesc
.getX(), eventDesc
.getY());
2000 if (clickPos
.x
< 0.f
||
2008 _RightClickLastPos
= clickPos
;
2009 return CInterfaceGroup::handleEvent(event
);
2013 if (event
.getType() == NLGUI::CEventDescriptor::system
)
2015 NLGUI::CEventDescriptorSystem
&es
= (NLGUI::CEventDescriptorSystem
&) event
;
2016 if (es
.getEventTypeExtended() == NLGUI::CEventDescriptorSystem::activecalledonparent
)
2018 bool visible
= getActive();
2021 CInterfaceElement
*curr
= this->getParent();
2024 if (!curr
->getActive())
2029 curr
= curr
->getParent();
2043 return CInterfaceGroup::handleEvent(event
);
2046 //============================================================================================================
2047 void CGroupMap::pan(sint32 dx
, sint32 dy
)
2049 if (_MapTexW
* _Scale
!= 0.f
) _WorldOffset
.x
+= dx
* (_MapMaxCorner
.x
- _MapMinCorner
.x
) / (_MapTexW
* _Scale
);
2050 if (_MapTexH
* _Scale
!= 0.f
) _WorldOffset
.y
-= dy
* (_MapMaxCorner
.y
- _MapMinCorner
.y
) / (_MapTexH
* _Scale
);
2052 _WorldOffset
.x
= _Offset
.x
* (_MapMaxCorner
.x
- _MapMinCorner
.x
);
2053 _WorldOffset
.y
= _Offset
.y
* (_MapMaxCorner
.y
- _MapMinCorner
.y
);
2057 //============================================================================================================
2058 void CGroupMap::setActive(bool active
)
2060 bool visible
= active
;
2061 CInterfaceElement
*curr
= this->getParent();
2064 if (!curr
->getActive())
2069 curr
= curr
->getParent();
2075 CInterfaceGroup::setActive(active
);
2082 //============================================================================================================
2083 void CGroupMap::loadPlayerPos()
2085 if (_PlayerPosLoadFailure
) return;
2086 _PlayerPosLoadFailure
= true;
2087 if (_PlayerPosMaterial
.empty())
2089 std::string fullName
= NLMISC::CPath::lookup(_PlayerPosTexName
, false, false);
2090 if (fullName
.empty())
2092 nlwarning("Can't player pos texture %s", _PlayerPosTexName
.c_str());
2097 if (bm
.open(fullName
))
2101 NLMISC::CBitmap::loadSize(fullName
, w
, h
);
2103 catch(const NLMISC::Exception
&e
)
2105 nlwarning(e
.what());
2111 nlwarning("Can't open player pos texture %s", fullName
.c_str());
2114 _PlayerPosTF
= Driver
->createTextureFile(fullName
);
2115 if (!_PlayerPosTF
) return;
2116 _PlayerPosLoadFailure
= false;
2117 _PlayerPosTF
->setWrapS(NL3D::UTexture::Clamp
);
2118 _PlayerPosTF
->setWrapT(NL3D::UTexture::Clamp
);
2121 _PlayerPosMaterial
.setTexture(_PlayerPosTF
);
2124 //============================================================================================================
2125 void CGroupMap::reload()
2127 if (!_CurMap
|| !getActive()) return;
2129 SMap
* current
= _CurMap
;
2135 //============================================================================================================
2136 void CGroupMap::loadMap()
2138 _MapLoadFailure
= true;
2139 if (!_CurMap
) return;
2141 _MapTexture
= _CurMap
->BitmapName
;
2143 // call lua game:onLoadMap() function if present
2144 // avoid deadlock if called recursively
2145 if (!_LuaLoadMapEntered
)
2147 _LuaLoadMapEntered
= true;
2148 CLuaState
*ls
= CLuaManager::getInstance().getLuaState();
2150 CLuaStackRestorer
lsr(ls
, ls
->getTop());
2151 ls
->pushGlobalTable();
2153 CLuaObject
game(*ls
);
2154 game
= game
["game"];
2155 if (!game
["onLoadMap"].isNil())
2160 CLuaIHM::pushReflectableOnStack(*ls
, this);
2161 if (game
.callMethodByNameNoThrow("onLoadMap", numArg
, numResult
))
2163 if (ls
->isString(1))
2165 if (!NLMISC::CPath::lookup(ls
->toString(1), false, false).empty())
2166 _MapTexture
= ls
->toString(1);
2168 nlwarning("Custom map texture not found '%s' for map '%s'", ls
->toString(1), _MapTexture
.c_str());
2173 _LuaLoadMapEntered
= false;
2176 std::string fullName
= NLMISC::CPath::lookup(_MapTexture
, false, false);
2177 if (fullName
.empty())
2179 nlwarning("Can't find map %s", _MapTexture
.c_str());
2184 if (bm
.open(fullName
))
2188 NLMISC::CBitmap::loadSize(fullName
, w
, h
);
2190 catch(const NLMISC::Exception
&e
)
2192 nlwarning(e
.what());
2198 nlwarning("Can't open map %s", _MapTexture
.c_str());
2201 _MapTF
= Driver
->createTextureFile(fullName
);
2204 _MapMaterial
.setTexture(0, _MapTF
);
2205 _MapTF
->setWrapS(NL3D::UTexture::Clamp
);
2206 _MapTF
->setWrapT(NL3D::UTexture::Clamp
);
2207 _MapTF
->setEnlargeCanvasNonPOW2Tex(true);
2210 // island are already pow2 textures
2211 // compute the real size
2212 // (1 pixel per metter, hardcoded for now)
2213 _MapTexW
= (uint32
) (ISLAND_PIXEL_PER_METER
* (_CurMap
->MaxX
- _CurMap
->MinX
));
2214 _MapTexH
= (uint32
) (ISLAND_PIXEL_PER_METER
* (_CurMap
->MaxY
- _CurMap
->MinY
));
2217 nlwarning("Island real width > texture width, snapshot not up-to-date ? (island = %s)", _CurMap
->Name
.c_str());
2222 nlwarning("Island real height > texture height, snapshot not up-to-date ? (island = %s)", _CurMap
->Name
.c_str());
2225 _URatio
= w
!= 0 ? (float) _MapTexW
/ w
: 0.f
;
2226 _VRatio
= h
!= 0 ? (float) _MapTexH
/ h
: 0.f
;
2230 // must raise to next power of 2 & scale uvs accordingly
2233 _URatio
= (float) w
/ (float) NLMISC::raiseToNextPowerOf2(w
);
2234 _VRatio
= (float) h
/ (float) NLMISC::raiseToNextPowerOf2(h
);
2236 _MapLoadFailure
= false;
2240 //============================================================================================================
2241 void CGroupMap::unloadMap()
2243 // remove texture from the material
2244 if (_MapTF
) Driver
->deleteTextureFile(_MapTF
);
2246 if (_PlayerPosTF
) Driver
->deleteTextureFile(_PlayerPosTF
);
2247 _PlayerPosTF
= NULL
;
2248 _MapMaterial
.setTexture(0,NULL
);
2249 _MapMaterial
.setTexture(1,NULL
);
2252 _MapLoadFailure
= false;
2255 //============================================================================================================
2256 void CGroupMap::updateContinentInfo()
2262 //============================================================================================================
2263 void CGroupMap::setMap(SMap
*map
)
2266 if ((_CurMap
!= NULL
) && (_CurMap
->Name
== map
->Name
)) return;
2268 // Unload and reset all stuff
2272 _CurContinent
= ContinentMngr
.get(_CurMap
->ContinentName
);
2273 _MapMinCorner
.x
= _CurMap
->MinX
;
2274 _MapMinCorner
.y
= _CurMap
->MinY
;
2275 _MapMaxCorner
.x
= _CurMap
->MaxX
;
2276 _MapMaxCorner
.y
= _CurMap
->MaxY
;
2277 if (_MapMinCorner
.x
> _MapMaxCorner
.x
) std::swap(_MapMinCorner
.x
, _MapMaxCorner
.x
);
2278 if (_MapMinCorner
.y
> _MapMaxCorner
.y
) std::swap(_MapMinCorner
.y
, _MapMaxCorner
.y
);
2284 createContinentLandMarks();
2286 nlinfo("setMap (%f,%f) (%f,%f)", _CurMap
->MinX
, _CurMap
->MinY
, _CurMap
->MaxX
, _CurMap
->MaxY
);
2290 CGroupHTML
*groupHtml
= dynamic_cast<CGroupHTML
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:lm_events:html"));
2294 groupHtml
->setHome(groupHtml
->Home
+toString("&min_x=%f&min_y=%f&max_x=%f&max_y=%f", _CurMap
->MinX
, _CurMap
->MinY
, _CurMap
->MaxX
, _CurMap
->MaxY
));
2295 groupHtml
->browse(groupHtml
->Home
.c_str());
2299 if (_CurContinent
!= NULL
)
2300 _MapMaterial
.setTexture(1, _CurContinent
->FoW
.Tx
);
2302 _MapMaterial
.setTexture(1, NULL
);
2304 // disable the map_back button for islands (islands can't be seen on the world map)
2305 CInterfaceGroup
*gc
= getParentContainer();
2308 CCtrlBase
*mapBack
= gc
->getCtrl("map_back");
2309 if (mapBack
) mapBack
->setActive(!_IsIsland
);
2316 //============================================================================================================
2317 void CGroupMap::setMap(const string
&mapName
)
2319 if ((_CurMap
!= NULL
) && (_CurMap
->Name
== mapName
)) return;
2321 // Unload and reset all stuff
2328 for (i
= 0; i
< _WorldSheet
->Maps
.size(); ++i
)
2329 if (_WorldSheet
->Maps
[i
].Name
== mapName
)
2332 if (i
== _WorldSheet
->Maps
.size())
2334 nlwarning("Unknown map to set : %s", mapName
.c_str());
2337 setMap(&_WorldSheet
->Maps
[i
]);
2343 //============================================================================================================
2344 void CGroupMap::centerOnPlayer()
2346 if (_MapTexW
== 0 || _MapTexH
== 0) return;
2348 // Ensure good scale computed
2351 // Here, in some case (init, if the map is not displayed), scale is 0. Avoid div by 0.
2352 float lx
= (_MapTexW
* _Scale
);
2353 float ly
= (_MapTexH
* _Scale
);
2354 if(lx
==0.f
) lx
= 0.01f
;
2355 if(ly
==0.f
) ly
= 0.01f
;
2356 _WorldOffset
.x
= (_MapMaxCorner
.x
- _MapMinCorner
.x
) * (_MapX
- _WReal
* 0.5f
) / lx
;
2357 _WorldOffset
.y
= (_MapMaxCorner
.y
- _MapMinCorner
.y
) * (- _MapY
- _HReal
* 0.5f
) / ly
;
2362 //============================================================================================================
2363 void CGroupMap::centerOnWorldPos(const CVector2f
&worldPos
)
2366 worldToMap(mapPos
, worldPos
);
2369 mapToScreen(sx
, sy
, mapPos
);
2372 computeMapRectInsideGroup(x
, y
, w
, h
);
2375 if (sx
< getXReal())
2376 dx
= -(getXReal() - sx
+ w
/2);
2378 dx
= sx
- getXReal() - w
/2;
2380 if (sy
< getYReal())
2381 dy
= -(getYReal() - sy
+ h
/2);
2383 dy
= sy
- getYReal() - h
/2;
2388 //============================================================================================================
2389 void CGroupMap::setScale(float newUserScale
, const NLMISC::CVector2f
&/* center */)
2391 NLMISC::clamp(newUserScale
, 1.f
, computeUserScaleFromRealScale(getActualMaxScale()));
2393 _UserScale
= newUserScale
;
2399 //============================================================================================================
2400 void CGroupMap::setScale(float newScale
)
2402 sint32 centerX
= (2 * (_XReal
+ _MapX
) + std::min(_WReal
, _MapW
)) / 2;
2403 sint32 centerY
= (2 * (_YReal
+ _MapY
) + std::min(_HReal
, _MapH
)) / 2;
2404 NLMISC::CVector2f mapCoords
;
2405 screenToMap(mapCoords
, centerX
, centerY
);
2406 setScale(newScale
, mapCoords
);
2409 //============================================================================================================
2410 void CGroupMap::updateLandMarkList(TLandMarkButtonVect
&lmVect
)
2412 uint numLM
= (uint
)lmVect
.size();
2413 for(uint k
= 0; k
< numLM
; ++k
)
2415 CLandMarkButton
*lmb
= lmVect
[k
];
2418 updateButtonPos(*lmb
);
2423 //============================================================================================================
2424 void CGroupMap::updateLandMarkTextList(TLandMarkTextVect
&lmVect
)
2426 uint numLM
= (uint
)lmVect
.size();
2427 for(uint k
= 0; k
< numLM
; ++k
)
2429 CLandMarkText
*lmt
= lmVect
[k
];
2433 mapToWindowSnapped(x
, y
, lmt
->Pos
);
2440 //============================================================================================================
2441 void CGroupMap::updateMatchedLandmarks()
2443 CInterfaceGroup
*gc
= getParentContainer();
2446 // visible landmark count
2447 CViewText
*pVT
= dynamic_cast<CViewText
*>(gc
->getView("lm_count"));
2450 // show total landmark count if search filter has not been set
2451 uint c
= _MatchedLandmarks
.size();
2452 if (c
== 0 && _LandmarkFilter
.size() == 0)
2455 pVT
->setText(toString(c
));
2458 // list of matched landmarks
2459 CGroupList
*pL
= dynamic_cast<CGroupList
*>(gc
->getGroup("lm_result"));
2464 if (_LandmarkFilter
.size() == 0) return;
2466 // create result list
2467 for(uint k
= 0; k
< _MatchedLandmarks
.size(); ++k
)
2469 std::vector
<std::pair
<string
,string
> > params
;
2471 params
.push_back(std::pair
<string
,string
>("id", toString("lm%d", k
)));
2472 // ctrl base expects utf8 string to start with "u:"
2473 params
.push_back(std::pair
<string
,string
>("tooltip", "u:" + _MatchedLandmarks
[k
].Title
.toUtf8()));
2474 params
.push_back(std::pair
<string
,string
>("index", toString(k
)));
2476 CInterfaceGroup
*g
= CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL
->getId(), params
);
2481 CViewText
* t
= dynamic_cast<CViewText
*>(g
->getView("title"));
2484 t
->setSingleLineTextFormatTaged(_MatchedLandmarks
[k
].Title
.toUtf8());
2487 CViewBitmap
* b
= dynamic_cast<CViewBitmap
*>(g
->getView("icon"));
2490 b
->setTexture(_MatchedLandmarks
[k
].Options
.LandMarkTexNormal
);
2491 b
->setColor(_MatchedLandmarks
[k
].Options
.ColorNormal
);
2495 pL
->invalidateCoords();
2498 //============================================================================================================
2499 void CGroupMap::removeLandMarks(TLandMarkButtonVect
&lm
)
2501 uint numLM
= (uint
)lm
.size();
2502 for(uint k
= 0; k
< numLM
; ++k
)
2513 //============================================================================================================
2514 void CGroupMap::removeUserLandMarks()
2516 removeLandMarks(_UserLM
);
2520 //============================================================================================================
2521 void CGroupMap::createLMWidgets(const std::vector
<CContLandMark
> &lms
)
2523 // disable any match in "world" mode
2524 bool notWorldMode
= _CurMap
->Name
!= "world";
2526 for (uint32 k
= 0; k
< lms
.size(); ++k
)
2528 const CContLandMark
&rCLM
=lms
[k
];
2530 NLMISC::CVector2f mapPos
;
2531 worldToMap(mapPos
, rCLM
.Pos
);
2533 const char *ucsTmp
= CStringManagerClient::getPlaceLocalizedName(rCLM
.TitleTextID
);
2534 const std::string lcTitle
= toLower(ucsTmp
);
2536 bool searchMatch
= notWorldMode
&& _LandmarkFilter
.size() > 0 && filterLandmark(lcTitle
);
2538 _MatchedLandmarks
.push_back(SMatchedLandmark(rCLM
.Pos
, ucstring::makeFromUtf8(ucsTmp
), _ContinentLMOptions
));
2540 // Add button if not a region nor a place
2541 if ((rCLM
.Type
!= CContLandMark::Region
) && (rCLM
.Type
!= CContLandMark::Place
) &&
2542 (rCLM
.Type
!= CContLandMark::Street
))
2544 if (rCLM
.Type
!= CContLandMark::Stable
)
2545 addLandMark(_ContinentLM
, mapPos
, ucstring::makeFromUtf8(ucsTmp
), _ContinentLMOptions
);
2547 addLandMark(_ContinentLM
, mapPos
, CI18N::get("uiStable"), _ContinentLMOptions
);
2548 _ContinentLM
.back()->Type
= rCLM
.Type
;
2549 _ContinentLM
.back()->SearchMatch
= searchMatch
;
2551 else // just add a text
2553 CLandMarkText
*pNewText
= new CLandMarkText(CViewBase::TCtorParam());
2554 pNewText
->setText(ucsTmp
);
2555 pNewText
->Pos
= mapPos
;
2556 pNewText
->setParent(this);
2557 pNewText
->setParentPosRef(Hotspot_BL
);
2558 pNewText
->setPosRef(Hotspot_MM
);
2559 if (rCLM
.Type
== CContLandMark::Region
)
2560 pNewText
->setFontSize(16);
2562 pNewText
->setColor(CRGBA(255,255,255,255));
2563 pNewText
->setShadow(true);
2564 pNewText
->setShadowOutline(false);
2565 pNewText
->setShadowColor(CRGBA(0,0,0,255));
2566 pNewText
->setModulateGlobalColor(false);
2567 pNewText
->Type
= rCLM
.Type
;
2568 pNewText
->SearchMatch
= searchMatch
;
2569 _ContinentText
.push_back(pNewText
);
2573 // If the name of the landmark is used as a click zone name of the current map, create a polybutton
2574 bool bFound
= false;
2575 for (uint i
= 0; i
< _CurMap
->Children
.size(); ++i
)
2577 if (rCLM
.TitleTextID
== _CurMap
->Children
[i
].ZoneName
)
2585 CPolyButton
*pPB
= new CPolyButton
;
2586 pPB
->build(rCLM
.Zone
, this, rCLM
.TitleTextID
);
2587 _PolyButtons
.push_back(pPB
);
2593 //============================================================================================================
2594 void CGroupMap::createContinentLandMarks()
2597 _MatchedLandmarks
.clear();
2599 if (_MapMode
!= MapMode_Normal
) return;
2600 if (_CurMap
== NULL
) return;
2603 removeLandMarks(_ContinentLM
);
2604 for (k
= 0; k
< _ContinentText
.size(); ++k
)
2605 delView(_ContinentText
[k
]);
2606 _ContinentText
.clear();
2607 removeLandMarks(_UserLM
);
2608 for (k
= 0; k
< _PolyButtons
.size(); ++k
)
2609 delCtrl(_PolyButtons
[k
]);
2610 _PolyButtons
.clear();
2612 // World map special case
2613 if (_CurMap
->Name
== "world")
2615 createLMWidgets(ContinentMngr
.WorldMap
);
2617 else if (_CurContinent
)
2619 // Continent Landmarks
2620 createLMWidgets(_CurContinent
->ContLandMarks
);
2622 for(k
= 0; k
< _CurContinent
->UserLandMarks
.size(); ++k
)
2624 NLMISC::CVector2f mapPos
;
2625 worldToMap(mapPos
, _CurContinent
->UserLandMarks
[k
].Pos
);
2627 CLandMarkOptions options
= getUserLandMarkOptions(k
);
2628 addLandMark(_UserLM
, mapPos
, _CurContinent
->UserLandMarks
[k
].Title
, options
);
2630 if (_LandmarkFilter
.size() > 0)
2632 if (filterLandmark(_CurContinent
->UserLandMarks
[k
].Title
))
2634 _MatchedLandmarks
.push_back(SMatchedLandmark(_CurContinent
->UserLandMarks
[k
].Pos
, _CurContinent
->UserLandMarks
[k
].Title
, options
));
2638 _UserLM
.back()->setActive(false);
2644 updateMatchedLandmarks();
2648 static void hideTeleportButtonsInPopupMenuIfNotEnoughPriv()
2650 bool showTeleport
= (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG());
2651 CInterfaceManager
*im
= CInterfaceManager::getInstance();
2653 CInterfaceElement
*ie
= CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport");
2654 if(ie
) ie
->setActive(showTeleport
);
2656 ie
= CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu_island:teleport");
2657 if(ie
) ie
->setActive(showTeleport
);
2659 ie
= CWidgetManager::getInstance()->getElementFromId("ui:interface:land_mark_menu:lmteleport");
2660 if(ie
) ie
->setActive(showTeleport
);
2662 ie
= CWidgetManager::getInstance()->getElementFromId("ui:interface:user_land_mark_menu:lmteleport");
2663 if(ie
) ie
->setActive(showTeleport
);
2665 ie
= CWidgetManager::getInstance()->getElementFromId("ui:interface:user_land_mark_menu_base:lmteleport");
2666 if(ie
) ie
->setActive(showTeleport
);
2669 //============================================================================================================
2670 void CGroupMap::setLandmarkFilter(const std::string
&s
)
2672 _LandmarkFilter
.clear();
2675 splitUCString(ucstring(toLower(s
)), ucstring(" "), _LandmarkFilter
);
2678 // recreate landmarks
2679 createContinentLandMarks();
2682 //============================================================================================================
2683 void CGroupMap::updateUserLandMarks()
2687 if (_MapMode
!= MapMode_Normal
) return;
2688 if (_CurMap
== NULL
|| _CurMap
->Name
== "world" || _CurContinent
== NULL
) return;
2691 removeLandMarks(_UserLM
);
2693 // Re create User Landmarks
2694 for(k
= 0; k
< _CurContinent
->UserLandMarks
.size(); ++k
)
2696 NLMISC::CVector2f mapPos
;
2697 worldToMap(mapPos
, _CurContinent
->UserLandMarks
[k
].Pos
);
2699 addLandMark(_UserLM
, mapPos
, _CurContinent
->UserLandMarks
[k
].Title
, getUserLandMarkOptions(k
));
2701 // hide landmark if not matching filter
2702 if (!filterLandmark(_CurContinent
->UserLandMarks
[k
].Title
))
2703 _UserLM
.back()->setActive(false);
2707 hideTeleportButtonsInPopupMenuIfNotEnoughPriv();
2711 //============================================================================================================
2712 CGroupMap::CLandMarkButton
*CGroupMap::createLandMarkButton(const CLandMarkOptions
&options
)
2714 CLandMarkButton
*lmb
= new CLandMarkButton(CViewBase::TCtorParam());
2715 static int statFool
= 0;
2716 lmb
->setId(this->getId()+":lm"+toString(statFool
++));
2717 lmb
->setTexture(options
.LandMarkTexNormal
);
2718 lmb
->setTextureOver(options
.LandMarkTexOver
);
2719 lmb
->setTexturePushed(options
.LandMarkTexPushed
);
2720 lmb
->setType(CCtrlButton::PushButton
);
2721 lmb
->setActionOnLeftClick("land_mark_selected");
2722 lmb
->setColor(options
.ColorNormal
);
2723 lmb
->setColorOver(options
.ColorOver
);
2724 lmb
->setColorPushed(options
.ColorPushed
);
2725 lmb
->setModulateGlobalColorAll(false);
2726 if (!options
.LandMarkMenu
.empty())
2728 lmb
->setActionOnRightClick("world_map_right_click");
2729 lmb
->setParamsOnRightClick(NLMISC::toString("map=%s|menu=%s", _Id
.c_str(), options
.LandMarkMenu
.c_str()));
2731 lmb
->setPosRef(Hotspot_MM
);
2735 //============================================================================================================
2736 CGroupMap::CLandMarkButton
*CGroupMap::createArkPointButton(const CArkPoint
&point
)
2738 CLandMarkButton
*lmb
= new CLandMarkButton(CViewBase::TCtorParam());
2739 static int statFool
= 0;
2740 lmb
->setId(this->getId()+":lm"+toString(statFool
++));
2741 lmb
->setTexture(point
.Texture
);
2742 lmb
->setTextureOver(point
.Texture
);
2743 lmb
->setTexturePushed(point
.Texture
);
2744 lmb
->setType(CCtrlButton::PushButton
);
2745 lmb
->setActionOnLeftClick(point
.LeftClickAction
);
2746 lmb
->setParamsOnLeftClick(point
.LeftClickParam
);
2747 lmb
->setActionOnRightClick(point
.RightClickAction
);
2748 lmb
->setParamsOnRightClick(point
.RightClickParam
);
2749 lmb
->setColor(point
.Color
);
2750 lmb
->setColorOver(point
.Color
);
2751 lmb
->setColorPushed(point
.Color
);
2752 lmb
->setModulateGlobalColorAll(false);
2754 lmb
->setPosRef(Hotspot_MM
);
2758 //============================================================================================================
2759 void CGroupMap::updateLandMarkButton(CLandMarkButton
*lmb
, const CLandMarkOptions
&options
)
2761 lmb
->setTexture(options
.LandMarkTexNormal
);
2762 lmb
->setTextureOver(options
.LandMarkTexOver
);
2763 lmb
->setTexturePushed(options
.LandMarkTexPushed
);
2765 lmb
->setColor(options
.ColorNormal
);
2766 lmb
->setColorOver(options
.ColorOver
);
2767 lmb
->setColorPushed(options
.ColorPushed
);
2770 //============================================================================================================
2771 bool CGroupMap::filterLandmark(const ucstring
&title
, const std::vector
<ucstring
> filter
, bool startsWith
) const
2773 if (filter
.size() > 0)
2775 ucstring lcTitle
= toLower(title
);
2778 if (lcTitle
.find(filter
[0]) != 0)
2785 for(uint i
= 0; i
< filter
.size(); ++i
)
2787 if (lcTitle
.find(filter
[i
]) == ucstring::npos
)
2797 //============================================================================================================
2798 bool CGroupMap::filterLandmark(const ucstring
&title
) const
2800 return filterLandmark(title
, _LandmarkFilter
);
2803 //============================================================================================================
2804 void CGroupMap::addLandMark(TLandMarkButtonVect
&destList
, const NLMISC::CVector2f
&pos
, const ucstring
&title
, const CLandMarkOptions
&options
)
2806 // create a new button and add it to the list
2807 CLandMarkButton
*lmb
= createLandMarkButton(options
);
2808 lmb
->setParent(this);
2810 lmb
->setDefaultContextHelp(title
.toUtf8());
2811 destList
.push_back(lmb
);
2815 //============================================================================================================
2816 void CGroupMap::addUserLandMark(const NLMISC::CVector2f
&pos
, const ucstring
&title
, NLMISC::CRGBA color
)
2818 if (_CurContinent
== NULL
) return;
2821 mapToWorld(ulm
.Pos
, pos
);
2824 _CurContinent
->UserLandMarks
.push_back(ulm
);
2826 CLandMarkOptions
options(_UserLMOptions
);
2827 options
.ColorNormal
= options
.ColorOver
= options
.ColorPushed
= color
;
2828 // create a new button and add it to the list
2829 CLandMarkButton
*lmb
= createLandMarkButton(options
);
2830 lmb
->setParent(this);
2832 lmb
->setDefaultContextHelp(title
.toUtf8());
2833 _UserLM
.push_back(lmb
);
2838 //============================================================================================================
2839 void CGroupMap::delArkPoints()
2841 for (uint i
= 0; i
< _RespawnLM
.size(); i
++)
2843 delCtrl(_RespawnLM
[i
]);
2844 _RespawnLM
[i
] = NULL
;
2849 //============================================================================================================
2850 void CGroupMap::addUserRespawnPoint(const NLMISC::CVector2f
&pos
)
2852 CRespawnPointsMsg rpm
;
2853 rpm
.NeedToReset
= false;
2854 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(pos
.x
*1000,pos
.y
*1000));
2855 addRespawnPoints(rpm
);
2859 //============================================================================================================
2860 CCtrlButton
*CGroupMap::addUserLandMark(const NLMISC::CVector2f
&pos
, const ucstring
&title
, const CUserLandMark::EUserLandMarkType lmType
)
2862 if (_CurContinent
== NULL
) return NULL
;
2863 nlassert(_CurContinent
->UserLandMarks
.size() == _UserLM
.size());
2864 // add the landmark in the current continent (for later save)
2865 // keep pos in world
2867 mapToWorld(ulm
.Pos
, pos
);
2869 ulm
.Type
= (uint8
)lmType
;
2870 _CurContinent
->UserLandMarks
.push_back(ulm
);
2872 // add a landmark with a menu to remove it
2873 addLandMark(_UserLM
, pos
, title
, getUserLandMarkOptions((uint32
)_CurContinent
->UserLandMarks
.size() - 1));
2875 // Save the config file each time a user landmark is created
2876 CInterfaceManager::getInstance()->saveLandmarks();
2878 return _UserLM
.back();
2881 //============================================================================================================
2882 CCtrlButton
* CGroupMap::getLandmarkCtrl(const std::string
&lmType
, uint lmIndex
) const
2884 CCtrlButton
*ctrl
= NULL
;
2885 if (lmType
== "user")
2887 if (lmIndex
< _UserLM
.size())
2889 ctrl
= _UserLM
[lmIndex
];
2891 else nlwarning("_UserLM index out of bounds (size:%u, index:%u)", (uint
)_UserLM
.size(), lmIndex
);
2893 else nlwarning("unsupported landmark type '%s'", lmType
.c_str());
2898 //============================================================================================================
2899 void CGroupMap::removeUserLandMark(CCtrlButton
*button
)
2901 if (_CurContinent
== NULL
) return;
2902 nlassert(_CurContinent
->UserLandMarks
.size() >= _UserLM
.size());
2903 for(uint k
= 0; k
< _UserLM
.size(); ++k
)
2905 if (_UserLM
[k
] == button
)
2907 delCtrl(_UserLM
[k
]);
2908 _UserLM
.erase(_UserLM
.begin() + k
);
2909 _CurContinent
->UserLandMarks
.erase(_CurContinent
->UserLandMarks
.begin() + k
);
2911 if (_CurContinent
->UserLandMarks
.size() > _UserLM
.size())
2913 // if user has over the limit landmarks, then rebuild visible markers
2914 updateUserLandMarks();
2917 CInterfaceManager::getInstance()->saveLandmarks();
2923 //============================================================================================================
2924 void CGroupMap::updateUserLandMark(CCtrlButton
*button
, const ucstring
&newTitle
, const CUserLandMark::EUserLandMarkType lmType
)
2926 if (_CurContinent
== NULL
) return;
2927 nlassert(_CurContinent
->UserLandMarks
.size() >= _UserLM
.size());
2928 for(uint k
= 0; k
< _UserLM
.size(); ++k
)
2930 if (_UserLM
[k
] == button
)
2932 _CurContinent
->UserLandMarks
[k
].Title
= newTitle
;
2933 _CurContinent
->UserLandMarks
[k
].Type
= (uint8
)lmType
;
2935 updateLandMarkButton(_UserLM
[k
], getUserLandMarkOptions(k
));
2936 button
->setDefaultContextHelp(newTitle
.toUtf8());
2938 CInterfaceManager::getInstance()->saveLandmarks();
2944 //============================================================================================================
2945 CUserLandMark
CGroupMap::getUserLandMark(CCtrlButton
*button
) const
2948 if (_CurContinent
== NULL
) return ulm
;
2949 nlassert(_CurContinent
->UserLandMarks
.size() >= _UserLM
.size());
2950 for(uint k
= 0; k
< _UserLM
.size(); ++k
)
2952 if (_UserLM
[k
] == button
)
2954 return _CurContinent
->UserLandMarks
[k
];
2962 //============================================================================================================
2963 uint
CGroupMap::getNumUserLandMarks() const
2965 if (_CurContinent
== NULL
) return 0;
2966 return (uint
)_CurContinent
->UserLandMarks
.size();
2968 //============================================================================================================
2969 CLandMarkOptions
CGroupMap::getUserLandMarkOptions(uint32 lmindex
) const
2971 if (_CurContinent
== NULL
|| _CurContinent
->UserLandMarks
.size() < lmindex
)
2972 return _UserLMOptions
;
2974 CLandMarkOptions
clmo(_UserLMOptions
);
2975 clmo
.ColorNormal
= clmo
.ColorOver
= clmo
.ColorPushed
= _CurContinent
->UserLandMarks
[lmindex
].getColor();
2982 //============================================================================================================
2983 void CGroupMap::updatePlayerPos()
2985 if (_MapMode
!= MapMode_SpawnSquad
)
2987 if (EntitiesMngr
.entities().empty()) return;
2988 if (!EntitiesMngr
.entity(0)) return;
2989 const NLMISC::CVectorD
&playerPosD
= EntitiesMngr
.entity(0)->pos();
2990 NLMISC::CVector
pos((float) playerPosD
.x
, (float) playerPosD
.y
, (float) playerPosD
.z
);
2991 // convert player pos into pos in map
2992 worldToMap(_PlayerPos
, pos
);
2993 // if player isn't in is last map anymore, see if in another island
2998 isInX
= (_CurMap
->MinX
<= pos
.x
) && (pos
.x
<= _CurMap
->MaxX
);
2999 isInY
= (_CurMap
->MinY
<= pos
.y
) && (pos
.y
<= _CurMap
->MaxY
);
3001 if(!isInX
|| !isInY
)
3004 for(uint k
= 0; k
< _Islands
.size(); ++k
)
3006 if (pos
.x
>= _Islands
[k
].MinX
&&
3007 pos
.y
>= _Islands
[k
].MinY
&&
3008 pos
.x
<= _Islands
[k
].MaxX
&&
3009 pos
.y
<= _Islands
[k
].MaxY
)
3012 setMap(&_Islands
[k
]);
3020 //============================================================================================================
3022 void CGroupMap::fitWindow()
3025 if (!EntitiesMngr.entity(0)) return;
3026 CGroupContainer *parentCont = this->getEnclosingContainer();
3027 if (!parentCont) return;
3028 CCtrlBase::updateCoords();
3029 const NLMISC::CVectorD &playerPosD = EntitiesMngr.entity(0)->pos();
3030 NLMISC::CVector pos((float) playerPosD.x, (float) playerPosD.y, (float) playerPosD.z);
3031 // convert player pos into pos in map
3032 worldToMap(_PlayerPos, pos);
3036 float mapWidthOnScreen = floorf(_MapTexW * _Scale);
3037 sint32 diffWReal = parentCont->getWReal() - _WReal;
3038 if ((float)_WReal >= mapWidthOnScreen)
3040 _Offset.x = - _PlayerPos.x;
3041 // _W is given by parent, so must update parent W
3042 if ((float)_WReal > mapWidthOnScreen)
3044 parentCont->setW((sint32) mapWidthOnScreen + diffWReal);
3049 NLMISC::clamp(_Offset.x, - _PlayerPos.x, - _PlayerPos.x + 1.f - _WReal / ((float) _MapTexW * _Scale));
3051 sint32 maxW = (sint32) mapWidthOnScreen;
3052 sint32 minW = std::min((sint32) mapWidthOnScreen, _MinW);
3053 parentCont->setMaxW(maxW + diffWReal);
3054 parentCont->setMinW(minW + diffWReal);
3055 parentCont->setPopupMaxW(maxW + diffWReal);
3056 parentCont->setPopupMinW(minW + diffWReal);
3057 if ((float)_WReal < minW)
3059 parentCont->setW((sint32) mapWidthOnScreen + diffWReal);
3065 //sint32 diffHReal = parentCont->getHReal() - _HReal;
3066 float mapHeightOnScreen = floorf(_MapTexH * _Scale);
3067 // parentCont->setPopupMaxH((sint32) mapHeightOnScreen + diffHReal);
3068 // parentCont->setPopupMinH((sint32) std::min(_MinH, (sint32) mapHeightOnScreen) + diffHReal);
3070 if ((float)_HReal >= mapHeightOnScreen)
3072 _Offset.y = - _PlayerPos.y;
3073 if ((float)_HReal > mapHeightOnScreen)
3075 _H = (sint32) mapHeightOnScreen;
3080 _H = std::max(_H, std::min(_MinH, (sint32) mapHeightOnScreen));
3081 NLMISC::clamp(_Offset.y, - _PlayerPos.y, - _PlayerPos.y + 1.f - _H / ((float) mapHeightOnScreen));
3087 //============================================================================================================
3088 void CGroupMap::evalMapOffset(float userScale
, float &scale
, sint32
&x
, sint32
&y
) const
3090 if (_MapTexW
== 0 || _MapTexH
== 0)
3096 float scaleX
= (float) _WReal
/ (float) _MapTexW
;
3097 float scaleY
= (float) _HReal
/ (float) _MapTexH
;
3098 scale
= std::min(scaleX
, scaleY
) * userScale
;
3099 // center the map if needed
3100 sint32 w
= (sint32
) (scale
* _MapTexW
);
3101 x
= (_WReal
- w
) / 2;
3102 sint32 h
= (sint32
) (scale
* _MapTexH
);
3103 y
= (h
- _HReal
) / 2;
3106 //============================================================================================================
3107 float CGroupMap::computeRealScaleFromUserScale(float userScale
) const
3109 float scaleX
= (float) _WReal
/ (float) _MapTexW
;
3110 float scaleY
= (float) _HReal
/ (float) _MapTexH
;
3111 return std::min(scaleX
, scaleY
) * userScale
;//
3114 //============================================================================================================
3115 float CGroupMap::computeUserScaleFromRealScale(float realScale
) const
3117 float scaleX
= (float) _WReal
/ (float) _MapTexW
;
3118 float scaleY
= (float) _HReal
/ (float) _MapTexH
;
3119 if (scaleX
<= 0.f
|| scaleY
<= 0.f
) return 1.f
;
3120 return realScale
/ std::min(scaleX
, scaleY
);
3123 //============================================================================================================
3124 void CGroupMap::updateScale()
3126 if (_MapTexW
== 0 || _MapTexH
== 0)
3128 _Scale
= _UserScale
;
3133 _Scale
= std::min(getActualMaxScale(), computeRealScaleFromUserScale(_UserScale
));
3135 // center the map if needed
3136 sint32 w
= (sint32
) (_Scale
* _MapTexW
);
3138 _MapX
= (_WReal
- w
) / 2;
3139 sint32 h
= (sint32
) (_Scale
* _MapTexH
);
3140 _MapY
= (h
- _HReal
) / 2;
3146 //=========================================================================================================
3147 void CGroupMap::computeMapRectInsideGroup(sint32
&x
, sint32
&y
, sint32
&w
, sint32
&h
) const
3149 x
= std::max((sint32
) 0, _MapX
);
3150 w
= std::min(_WReal
, _MapX
+ _MapW
);
3151 y
= std::max((sint32
) 0, _MapY
);
3152 h
= std::min(_HReal
, _MapY
+ _MapH
);
3153 y
= std::max((sint32
) 0, (_HReal
- _MapY
));
3156 //=========================================================================================================
3157 void CGroupMap::computeOffsets()
3159 if (_MapTexW
== 0 || _MapTexH
== 0)
3161 _WorldOffset
.set(0.f
, 0.f
);
3162 _Offset
.set(0.f
, 0.f
);
3166 // avoid div by 0 (nb: duno if those values can be negative...)
3167 float lx
= _MapMaxCorner
.x
- _MapMinCorner
.x
;
3168 float ly
= _MapMaxCorner
.y
- _MapMinCorner
.y
;
3169 if(lx
==0.f
) lx
= 0.01f
;
3170 if(ly
==0.f
) ly
= 0.01f
;
3171 _Offset
.x
= _WorldOffset
.x
/ lx
;
3172 _Offset
.y
= _WorldOffset
.y
/ ly
;
3174 float startCornerX
= _Offset
.x
+ _PlayerPos
.x
;
3175 if (_MapX
< 0) startCornerX
-= _MapX
/ (_MapTexW
* _Scale
);
3176 float startCornerY
= _Offset
.y
+ _PlayerPos
.y
;
3177 if (_MapY
> 0) startCornerY
+= _MapY
/ (_MapTexH
* _Scale
);
3178 float endCornerX
= startCornerX
;
3179 float endCornerY
= startCornerY
;
3180 NLMISC::clamp(endCornerX
, 0.f
, 1.f
- std::min(_MapW
, _WReal
) / ((float) _MapTexW
* _Scale
));
3181 NLMISC::clamp(endCornerY
, 0.f
, 1.f
- std::min(_MapH
, _HReal
) / ((float) _MapTexH
* _Scale
));
3182 _Offset
.x
+= endCornerX
- startCornerX
;
3183 _Offset
.y
+= endCornerY
- startCornerY
;
3186 //=========================================================================================================
3187 void CGroupMap::targetLandmark(CCtrlButton
*lm
)
3190 // continent landmarks
3193 TLandMarkButtonVect::iterator it
= std::find(_ContinentLM
.begin(), _ContinentLM
.end(),lm
);
3195 if (it
!= _ContinentLM
.end())
3197 ct
.setType(CCompassTarget::ContinentLandMark
);
3198 (*it
)->getContextHelp(ct
.Name
);
3199 mapToWorld(ct
.Pos
, (*it
)->Pos
);
3205 // mission landmarks
3206 it
= std::find(_MissionLM
.begin(), _MissionLM
.end(),lm
);
3208 if (it
!= _MissionLM
.end())
3210 ct
.setPositionState(_MissionPosStates
[it
- _MissionLM
.begin()]);
3211 (*it
)->getContextHelp(ct
.Name
);
3212 mapToWorld(ct
.Pos
, (*it
)->Pos
);
3220 it
= std::find(_UserLM
.begin(), _UserLM
.end(),lm
);
3222 if (it
!= _UserLM
.end())
3224 ct
.setType(CCompassTarget::UserLandMark
);
3225 (*it
)->getContextHelp(ct
.Name
);
3226 mapToWorld(ct
.Pos
, (*it
)->Pos
);
3236 // pos irrelevant for home, recomputed at each frame
3237 ct
.setType(CCompassTarget::Home
);
3238 ct
.Name
= CI18N::get("uiHome");
3245 // if in island -> no effect when choosing entry point for now
3246 it
= std::find(_RespawnLM
.begin(), _RespawnLM
.end(),lm
);
3248 if (it
!= _RespawnLM
.end())
3252 ct
.setType(CCompassTarget::Respawn
);
3253 (*it
)->getContextHelp(ct
.Name
);
3254 mapToWorld(ct
.Pos
, (*it
)->Pos
);
3257 // pos irrelevant for respawn point, recomputed at each frame
3258 if ((_MapMode
== MapMode_Death
) || (_MapMode
== MapMode_SpawnSquad
))
3260 _RespawnSelectedBitmap
->setParentPos(*it
);
3261 string sTmp
= (*it
)->getId();
3262 sTmp
= sTmp
.substr(sTmp
.rfind('_')+1, sTmp
.size());
3263 fromString(sTmp
, _RespawnSelected
);
3264 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3265 if (_MapMode
== MapMode_Death
)
3266 NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RESPAWN_PT")->setValue32(_RespawnSelected
);
3267 else if (_MapMode
== MapMode_SpawnSquad
)
3269 NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:SQUAD_RESPAWN_PT")->setValue32(_RespawnSelected
);
3270 // Close window containing the map
3271 CInterfaceGroup
*pGrp
= CWidgetManager::getInstance()->getWindow(this);
3272 if (pGrp
!= NULL
) pGrp
->setActive(false);
3282 if (lm
== _TargetLM
)
3284 // pos irrelevant for respwan, recomputed at each frame
3285 ct
.setType(CCompassTarget::Selection
);
3292 // animals landmarks
3293 if(_AnimalLM
.size() == _AnimalPosStates
.size())
3295 for(uint i
=0;i
<_AnimalLM
.size();i
++)
3297 if(_AnimalLM
[i
]==lm
)
3299 _AnimalLM
[i
]->getContextHelp(ct
.Name
);
3300 // copy The Animal Pos retriever into the compass
3301 ct
.setPositionState(_AnimalPosStates
[i
]);
3310 // teammates landmarks
3311 if(_TeammateLM
.size() == _TeammatePosStates
.size())
3313 for(uint i
=0;i
<_TeammateLM
.size();i
++)
3315 if(_TeammateLM
[i
]==lm
)
3317 _TeammateLM
[i
]->getContextHelp(ct
.Name
);
3318 // copy The Animal Pos retriever into the compass
3319 ct
.setPositionState(_TeammatePosStates
[i
]);
3328 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3329 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(_CompassId
));
3332 gc
->setActive(true);
3335 CWidgetManager::getInstance()->setTopWindow(gc
);
3340 //=========================================================================================================
3341 void CGroupMap::targetLandmarkResult(uint32 index
)
3343 if (index
> _MatchedLandmarks
.size()) return;
3346 ct
.Pos
= _MatchedLandmarks
[index
].Pos
;
3347 ct
.Name
= _MatchedLandmarks
[index
].Title
.toUtf8();
3348 // type sets compass arrow color
3349 ct
.setType(CCompassTarget::UserLandMark
);
3351 centerOnWorldPos(ct
.Pos
);
3353 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3354 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(_CompassId
));
3357 gc
->setActive(true);
3360 CWidgetManager::getInstance()->setTopWindow(gc
);
3364 //=========================================================================================================
3365 CGroupMap::CLandMarkButton
* CGroupMap::findClosestLandmark(const CVector2f
¢er
, const ucstring
&search
, bool startsWith
, const TLandMarkButtonVect
&landmarks
, float &closest
) const
3367 CLandMarkButton
*ret
= NULL
;
3369 std::vector
<ucstring
> keywords
;
3371 keywords
.push_back(search
);
3373 splitUCString(toLower(search
), ucstring(" "), keywords
);
3375 closest
= std::numeric_limits
<float>::max();
3376 for(TLandMarkButtonVect::const_iterator it
= landmarks
.begin(); it
!= landmarks
.end(); ++it
)
3379 (*it
)->getContextHelp(lc
);
3380 ucstring ulc
= ucstring::makeFromUtf8(lc
);
3381 if(filterLandmark(ulc
, keywords
, startsWith
)) {
3383 mapToWorld(pos
, (*it
)->Pos
);
3384 float dist
= distsqr(center
, pos
);
3396 //=========================================================================================================
3397 CGroupMap::CLandMarkText
* CGroupMap::findClosestLandmark(const CVector2f
¢er
, const ucstring
&search
, bool startsWith
, const TLandMarkTextVect
&landmarks
, float &closest
) const
3399 CLandMarkText
*ret
= NULL
;
3401 std::vector
<ucstring
> keywords
;
3403 keywords
.push_back(search
);
3405 splitUCString(toLower(search
), ucstring(" "), keywords
);
3407 closest
= std::numeric_limits
<float>::max();
3408 for(TLandMarkTextVect::const_iterator it
= landmarks
.begin(); it
!= landmarks
.end(); ++it
)
3411 lc
= CUtfStringView((*it
)->getText()).toUtf16();
3412 if(filterLandmark(lc
, keywords
, startsWith
)) {
3414 mapToWorld(pos
, (*it
)->Pos
);
3415 float dist
= distsqr(center
, pos
);
3427 bool CGroupMap::targetLandmarkByName(const ucstring
&search
, bool startsWith
) const
3430 CLandMarkButton
* lm
;
3432 float closest
= std::numeric_limits
<float>::max();
3435 mapToWorld(center
, _PlayerPos
);
3437 lm
= findClosestLandmark(center
, search
, startsWith
, _UserLM
, dist
);
3438 if (lm
&& dist
< closest
)
3440 ct
.setType(CCompassTarget::UserLandMark
);
3441 mapToWorld(ct
.Pos
, lm
->Pos
);
3442 lm
->getContextHelp(ct
.Name
);
3447 // only check other types if user landmark was not found
3450 lm
= findClosestLandmark(center
, search
, startsWith
, _ContinentLM
, dist
);
3451 if (lm
&& dist
< closest
)
3453 ct
.setType(CCompassTarget::ContinentLandMark
);
3454 mapToWorld(ct
.Pos
, lm
->Pos
);
3455 lm
->getContextHelp(ct
.Name
);
3461 lmt
= findClosestLandmark(center
, search
, startsWith
, _ContinentText
, dist
);
3462 if (lmt
&& dist
< closest
)
3464 ct
.setType(CCompassTarget::ContinentLandMark
);
3465 mapToWorld(ct
.Pos
, lmt
->Pos
);
3466 ct
.Name
= lmt
->getText();
3474 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3475 CGroupCompas
*gc
= dynamic_cast<CGroupCompas
*>(CWidgetManager::getInstance()->getElementFromId(_CompassId
));
3478 gc
->setActive(true);
3481 CWidgetManager::getInstance()->setTopWindow(gc
);
3488 //=========================================================================================================
3489 void CGroupMap::getLandmarkPosition(const CCtrlButton
*lm
, NLMISC::CVector2f
&worldPos
)
3493 // continent landmarks
3495 TLandMarkButtonVect::iterator it
= std::find(_ContinentLM
.begin(), _ContinentLM
.end(),lm
);
3497 if (it
!= _ContinentLM
.end())
3499 mapToWorld(worldPos
, (*it
)->Pos
);
3504 // mission landmarks
3505 it
= std::find(_MissionLM
.begin(), _MissionLM
.end(),lm
);
3507 if (it
!= _MissionLM
.end())
3509 mapToWorld(worldPos
, (*it
)->Pos
);
3515 it
= std::find(_UserLM
.begin(), _UserLM
.end(),lm
);
3517 if (it
!= _UserLM
.end())
3519 mapToWorld(worldPos
, (*it
)->Pos
);
3525 // if in island -> no effect when choosing entry point for now
3526 it
= std::find(_RespawnLM
.begin(), _RespawnLM
.end(),lm
);
3527 if (it
!= _RespawnLM
.end())
3531 mapToWorld(worldPos
, (*it
)->Pos
);
3536 worldPos
= NLMISC::CVector2f::Null
;
3539 //=========================================================================================================
3540 void CGroupMap::addRespawnPoints(const CRespawnPointsMsg
&rpm
)
3542 _RespawnPosReseted
= false;
3543 if (rpm
.NeedToReset
)
3545 _RespawnPosReseted
= true;
3546 _RespawnPos
.clear();
3548 for (uint32 i
= 0; i
< rpm
.RespawnPoints
.size(); ++i
)
3549 _RespawnPos
.push_back(rpm
.RespawnPoints
[i
]);
3550 // Ensure there is at least one respawn point
3551 // nlassert(!_RespawnPos.empty());
3553 // Choose the good map ! (select the first respawn point and check for first matching bounding box map
3554 if (_MapMode
!= MapMode_Death
) return;
3555 if (_RespawnPos
.empty()) return;
3557 CWorldSheet
*pWS
= dynamic_cast<CWorldSheet
*>(SheetMngr
.get(CSheetId("ryzom.world")));
3558 if (pWS
== NULL
) return;
3560 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3561 if (pIM
== NULL
) return;
3563 NLMISC::CVector2f
rpWorldPos(_RespawnPos
[0].x
* 0.001f
, _RespawnPos
[0].y
* 0.001f
);
3565 for (uint32 i
= 0; i
< pWS
->Maps
.size(); ++i
)
3567 SMap
&rMap
= pWS
->Maps
[i
];
3568 if (rMap
.ContinentName
.empty()) continue;
3570 if ((rpWorldPos
.x
>= rMap
.MinX
) &&
3571 (rpWorldPos
.x
<= rMap
.MaxX
) &&
3572 (rpWorldPos
.y
>= rMap
.MinY
) &&
3573 (rpWorldPos
.y
<= rMap
.MaxY
))
3581 //=========================================================================================================
3582 void CGroupMap::addArkPoint(const CArkPoint
&point
) {
3583 _ArkPoints
.push_back(point
);
3585 if (_MapMode
!= MapMode_Death
) return;
3586 if (_ArkPoints
.empty()) return;
3588 CWorldSheet
*pWS
= dynamic_cast<CWorldSheet
*>(SheetMngr
.get(CSheetId("ryzom.world")));
3589 if (pWS
== NULL
) return;
3591 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3592 if (pIM
== NULL
) return;
3594 NLMISC::CVector2f
rpWorldPos(point
.x
* 0.001f
, point
.y
* 0.001f
);
3596 for (uint32 i
= 0; i
< pWS
->Maps
.size(); ++i
)
3598 SMap
&rMap
= pWS
->Maps
[i
];
3599 if (rMap
.ContinentName
.empty()) continue;
3601 if ((rpWorldPos
.x
>= rMap
.MinX
) &&
3602 (rpWorldPos
.x
<= rMap
.MaxX
) &&
3603 (rpWorldPos
.y
>= rMap
.MinY
) &&
3604 (rpWorldPos
.y
<= rMap
.MaxY
))
3613 //=========================================================================================================
3614 void CGroupMap::serialConfig(NLMISC::IStream
&f
)
3616 sint ver
= f
.serialVersion(3);
3617 f
.serial(_UserScale
);
3625 // dummy read the old _Offset, and reset to 0.
3627 _WorldOffset
.set(0.f
, 0.f
);
3628 _Offset
.set(0.f
, 0.f
);
3632 f
.serial(_WorldOffset
);
3635 // Avoid bad saved WorldOffset
3638 if(!isValidDouble(_WorldOffset
.x
) || !isValidDouble(_WorldOffset
.y
))
3639 _WorldOffset
.set(0,0);
3642 // In version 3 we do not read the _H anymore
3646 // Yoyo: patch to avoid old "respawn map hid at second time" bug
3653 //=========================================================================================================
3654 sint32
CGroupMap::getRespawnSelected() const
3656 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3657 CCDBNodeLeaf
*pNL
= NULL
;
3658 if (_MapMode
== MapMode_Death
)
3659 pNL
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RESPAWN_PT",false);
3660 else if (_MapMode
== MapMode_SpawnSquad
)
3661 pNL
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:SQUAD_RESPAWN_PT",false);
3663 return pNL
->getValue32();
3667 //=========================================================================================================
3668 void CGroupMap::setRespawnSelected(sint32 nSpawnPointIndex
)
3670 if (_RespawnPos
.empty()) return;
3671 if (nSpawnPointIndex
< 0) return;
3672 if ((uint32
)nSpawnPointIndex
>= _RespawnPos
.size()) return;
3673 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
3674 CCDBNodeLeaf
*pNL
= NULL
;
3675 if (_MapMode
== MapMode_Death
)
3676 pNL
= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:RESPAWN_PT",false);
3677 else if (_MapMode
== MapMode_SpawnSquad
)
3678 pNL
= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:SQUAD_RESPAWN_PT",false);
3680 pNL
->setValue32(nSpawnPointIndex
);
3681 _RespawnSelected
= nSpawnPointIndex
;
3682 _RespawnPosReseted
= false;
3686 //=========================================================================================================
3687 SMap
*CGroupMap::getParentMap(SMap
*map
)
3689 if (map
== NULL
) return NULL
;
3691 for (uint32 i
= 0; i
< _WorldSheet
->Maps
.size(); ++i
)
3693 bool bFound
= false;
3694 SMap
*pM
= &_WorldSheet
->Maps
[i
];
3695 for (uint32 j
= 0; j
< pM
->Children
.size(); ++j
)
3697 if (pM
->Children
[j
].Name
== map
->Name
)
3709 //=========================================================================================================
3710 std::string
CGroupMap::getContinentName() const
3712 if (_CurMap
== NULL
) return "";
3714 return toLowerAscii(_CurMap
->ContinentName
);
3717 //=========================================================================================================
3718 std::string
CGroupMap::getMapTexture() const
3720 return toLowerAscii(_MapTexture
);
3723 //=========================================================================================================
3724 int CGroupMap::luaReload(CLuaState
&ls
)
3726 CLuaIHM::checkArgCount(ls
, "reload", 0);
3731 //=========================================================================================================
3732 int CGroupMap::luaIsIsland(CLuaState
&ls
)
3734 CLuaIHM::checkArgCount(ls
, "isIsland", 0);
3740 /////////////////////
3741 // ACTION HANDLERS //
3742 /////////////////////
3744 //=========================================================================================================
3745 void CGroupMap::updateClosestLandMarkMenu(const std::string
&menu
, const NLMISC::CVector2f
&pos
) const
3747 static uint nbShowLandmarks
= 5;
3748 static uint nbShowLandmarksMax
= 5;
3750 const CGroupMenu
*pMenu
= dynamic_cast<CGroupMenu
*>(CWidgetManager::getInstance()->getElementFromId(menu
));
3753 CGroupSubMenu
*rootMenu
= pMenu
->getRootMenu();
3754 if (!rootMenu
) return;
3756 // remove previous markers from menu
3757 for(uint i
= 0; i
< nbShowLandmarksMax
; ++i
)
3759 std::string lineId
= toString("%s:lmcosest%d", menu
.c_str(), i
);
3760 sint index
= rootMenu
->getLineFromId(lineId
);
3761 if (index
< 0) break;
3762 rootMenu
->removeLine(index
);
3765 // no continent selected (ie world map view)
3766 if (!_CurContinent
) return;
3768 // sort landmarks, keep indices
3769 typedef std::pair
<uint
, float> TSortedDistPair
;
3770 std::vector
<TSortedDistPair
> sortedIndices
;
3771 for(uint i
= 0; i
< _CurContinent
->UserLandMarks
.size(); ++i
)
3773 float dist
= distsqr(pos
, _CurContinent
->UserLandMarks
[i
].Pos
);
3774 if (sortedIndices
.empty())
3776 sortedIndices
.push_back(TSortedDistPair(i
, dist
));
3781 for(uint j
= 0; j
< sortedIndices
.size(); j
++)
3783 if (dist
< sortedIndices
[j
].second
)
3785 sortedIndices
.insert(sortedIndices
.begin() + j
, TSortedDistPair(i
, dist
));
3787 if (sortedIndices
.size() > nbShowLandmarks
)
3789 sortedIndices
.pop_back();
3795 if (!found
&& sortedIndices
.size() < nbShowLandmarks
)
3797 sortedIndices
.push_back(TSortedDistPair(i
, dist
));
3802 // add landmarks to menu
3803 uint lineIndex
= rootMenu
->getNumLines();
3804 for(uint i
= 0; i
< sortedIndices
.size(); ++i
)
3806 uint32 index
= sortedIndices
[i
].first
;
3807 ucstring name
= ucstring(toString("%.2fm ", sqrt(sortedIndices
[i
].second
))) + _CurContinent
->UserLandMarks
[index
].Title
;
3808 std::string lineId
= toString("%s:lmcosest%d", menu
.c_str(), i
);
3809 std::string ahParams
= toString("type=user|map=%s|index=%d", _Id
.c_str(), index
);
3811 CViewTextMenu
* vt
= rootMenu
->addLine(std::string(), "map_landmark_by_index", ahParams
, lineId
.c_str(), "", "", false, false, false);
3814 vt
->setSingleLineTextFormatTaged(name
.toUtf8());
3815 // TODO: should calculate from mouse pos and client width
3816 vt
->setLineMaxW(800);
3818 CLandMarkOptions options
= getUserLandMarkOptions(index
);
3820 typedef std::pair
<std::string
, std::string
> TTmplParams
;
3821 std::vector
<TTmplParams
> vparams
;
3822 vparams
.push_back(TTmplParams("id", toString("lmicon%d", i
)));
3823 vparams
.push_back(TTmplParams("sizeref", ""));
3824 vparams
.push_back(TTmplParams("icon_texture", options
.LandMarkTexNormal
));
3825 vparams
.push_back(TTmplParams("icon_color", options
.ColorNormal
.toString()));
3827 CInterfaceGroup
*pUGLeft
= CWidgetManager::getInstance()->getParser()->createGroupInstance("landmark_row_icon", lineId
, vparams
);
3829 rootMenu
->setUserGroupLeft(lineIndex
, pUGLeft
, true);
3831 rootMenu
->setRightClickHandler(lineIndex
, "map_landmark_by_index");
3832 rootMenu
->setRightClickHandlerParam(lineIndex
, toString("%s|menu=%s_base", ahParams
.c_str(), options
.LandMarkMenu
.c_str()));
3837 //=========================================================================================================
3838 // remap caller with landmark using index/type and call popup menu or set compass target if no menu is set
3839 class CAHMapLandmarkByIndex
: public IActionHandler
3841 virtual void execute (CCtrlBase
* pCaller
, const string
¶ms
)
3843 const std::string mapName
= getParam(params
, "map");
3844 const std::string lmType
= getParam(params
, "type");
3845 const std::string menuId
= getParam(params
, "menu");
3847 if (!fromString(getParam(params
, "index"), index
)) return;
3849 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(mapName
));
3852 // remap caller to landmark from menu row
3853 CCtrlButton
* pButton
= map
->getLandmarkCtrl(lmType
, index
);
3854 if (!pButton
) return;
3857 map
->targetLandmark(pButton
);
3859 CAHManager::getInstance()->runActionHandler("active_menu", pButton
, toString("pushmodal=true|popmodal=false|menu=%s", menuId
.c_str()));
3862 REGISTER_ACTION_HANDLER(CAHMapLandmarkByIndex
, "map_landmark_by_index");
3864 //=========================================================================================================
3865 // Set landmark filter
3866 class CAHLandMarkFilter
: public IActionHandler
3868 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
3870 string id
= getParam(params
, "map");
3872 CGroupMap
* map
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(id
));
3875 string text
= getParam(params
, "text");
3876 if (text
.empty() && params
.find("text=") == std::string::npos
)
3878 string group
= getParam(params
, "group");
3879 CGroupEditBox
* eb
= dynamic_cast<CGroupEditBox
*>(CWidgetManager::getInstance()->getElementFromId(group
));
3882 text
= eb
->getInputString();
3885 map
->setLandmarkFilter(text
);
3888 REGISTER_ACTION_HANDLER(CAHLandMarkFilter
, "land_mark_filter");
3890 //=========================================================================================================
3891 // Landmark selected from result list
3892 class CAHLandMarkResultSelected
: public IActionHandler
3894 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
3896 string id
= getParam(params
, "map");
3897 CGroupMap
* map
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(id
));
3901 string nr
= getParam(params
, "index");
3902 if (!fromString(nr
, index
)) return;
3904 map
->targetLandmarkResult(index
);
3907 REGISTER_ACTION_HANDLER(CAHLandMarkResultSelected
, "land_mark_result_selected");
3909 //=========================================================================================================
3910 // A land mark button has been pushed
3911 class CAHLandMarkSelected
: public IActionHandler
3913 virtual void execute (CCtrlBase
*pCaller
, const string
&/* params */)
3915 CCtrlButton
*button
= dynamic_cast<CCtrlButton
*>(pCaller
);
3916 if (!button
) return;
3917 // Select the landmark as the current target
3918 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(button
->getParent());
3920 map
->targetLandmark(button
);
3923 REGISTER_ACTION_HANDLER(CAHLandMarkSelected
, "land_mark_selected");
3925 //=========================================================================================================
3926 // Remove a user landmark
3927 class CAHRemoveUserLandMark
: public IActionHandler
3929 virtual void execute (CCtrlBase
*pCaller
, const string
&/* params */)
3931 CCtrlButton
*button
= dynamic_cast<CCtrlButton
*>(pCaller
);
3932 if (!button
) return;
3933 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(button
->getParent());
3935 map
->removeUserLandMark(button
);
3936 // close the rename window & create window
3937 closeLandMarkNameDialog();
3938 LastSelectedLandMark
= NULL
;
3941 REGISTER_ACTION_HANDLER(CAHRemoveUserLandMark
, "remove_user_landmark");
3943 //=========================================================================================================
3944 // Rename a user land mark
3945 class CAHRenameUserLandMark
: public IActionHandler
3947 virtual void execute (CCtrlBase
*pCaller
, const string
&/* params */)
3949 LastSelectedLandMark
= dynamic_cast<CCtrlButton
*>(pCaller
);
3950 if (!LastSelectedLandMark
) return;
3952 popupLandMarkNameDialog();
3955 REGISTER_ACTION_HANDLER(CAHRenameUserLandMark
, "rename_user_landmark");
3958 //=========================================================================================================
3959 // Validate user landmark name
3960 class CAHValidateUserLandMarkName
: public IActionHandler
3962 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* params */)
3964 CInterfaceManager
*im
= CInterfaceManager::getInstance();
3965 CInterfaceGroup
*ig
= dynamic_cast<CInterfaceGroup
*>(CWidgetManager::getInstance()->getElementFromId(WIN_LANDMARK_NAME
));
3967 CGroupEditBox
*eb
= dynamic_cast<CGroupEditBox
*>(ig
->getGroup("eb"));
3969 ig
->setActive(false);
3971 CGroupContainer
*gc
= dynamic_cast<CGroupContainer
*>(CWidgetManager::getInstance()->getElementFromId(WIN_LANDMARK_NAME
));
3973 // Retrieve ComboBox to get the position(ordered landmark type) of the selected item
3974 CDBGroupComboBox
*cb
= dynamic_cast<CDBGroupComboBox
*>(gc
->getGroup("landmarktypes"));
3976 CUserLandMark::EUserLandMarkType landMarkType
= CUserLandMark::Misc
;
3977 sint8 nLandMarkType
= cb
->getTextId( CDBManager::getInstance()->getDbProp( "UI:TEMP:LANDMARKTYPE" )->getValue8());
3978 if (nLandMarkType
>=0 && nLandMarkType
<=CUserLandMark::UserLandMarkTypeCount
)
3980 landMarkType
= (CUserLandMark::EUserLandMarkType
)nLandMarkType
;
3983 if (LastSelectedLandMark
)
3985 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(LastSelectedLandMark
->getParent());
3987 // update existing landmark
3988 map
->updateUserLandMark(LastSelectedLandMark
, ucstring::makeFromUtf8(eb
->getInputString()), landMarkType
);
3992 // create a new landmark
3993 if (!LastClickedMap
) return;
3994 if( UseUserPositionForLandMark
)
3996 LastClickedMap
->addUserLandMark(LastClickedMap
->getPlayerPos(), ucstring::makeFromUtf8(eb
->getInputString()), landMarkType
);
4000 LastClickedMap
->addUserLandMark(LastClickedMap
->getRightClickLastPos(), ucstring::makeFromUtf8(eb
->getInputString()), landMarkType
);
4002 LastClickedMap
->invalidateCoords();
4006 REGISTER_ACTION_HANDLER(CAHValidateUserLandMarkName
, "validate_user_landmark_name");
4008 //=========================================================================================================
4009 void createUserLandMark(CCtrlBase
* /* pCaller */, const string
&/* params */)
4011 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4012 // pop the rename dialog
4013 LastClickedMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
4014 if (LastClickedMap
->isInDeathMode()) return;
4015 LastSelectedLandMark
= NULL
;
4016 popupLandMarkNameDialog();
4019 // create a new landmark after giving its name
4020 class CAHCreateUserLandMark
: public IActionHandler
4022 virtual void execute (CCtrlBase
*pCaller
, const string
¶ms
)
4024 UseUserPositionForLandMark
= false;
4025 createUserLandMark(pCaller
,params
);
4028 REGISTER_ACTION_HANDLER(CAHCreateUserLandMark
, "create_user_landmark");
4030 // create a new landmark at user position after giving its name
4031 class CAHCreateUserLandMarkAtUserPos
: public IActionHandler
4033 virtual void execute (CCtrlBase
*pCaller
, const string
¶ms
)
4035 UseUserPositionForLandMark
= true;
4036 createUserLandMark(pCaller
,params
);
4039 REGISTER_ACTION_HANDLER(CAHCreateUserLandMarkAtUserPos
, "create_user_landmark_at_user_pos");
4042 //=========================================================================================================
4044 class CAHMapZoomIn
: public IActionHandler
4046 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
4048 std::string map
= getParam(params
, "map");
4049 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4050 CGroupMap
*gm
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4052 NLMISC::CVector2f center
;
4053 gm
->windowToMap(center
, gm
->getWReal() / 2, gm
->getHReal() / 2);
4054 gm
->setScale(gm
->getScale() * 1.3f
, center
);
4057 REGISTER_ACTION_HANDLER(CAHMapZoomIn
, "map_zoom_in");
4059 //=========================================================================================================
4061 class CAHMapZoomOut
: public IActionHandler
4063 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
4065 std::string map
= getParam(params
, "map");
4066 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4067 CGroupMap
*gm
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4069 NLMISC::CVector2f center
;
4070 gm
->windowToMap(center
, gm
->getWReal() / 2, gm
->getHReal() / 2);
4071 gm
->setScale(gm
->getScale() * 0.7f
, center
);
4074 REGISTER_ACTION_HANDLER(CAHMapZoomOut
, "map_zoom_out");
4076 //=========================================================================================================
4077 // center map on the player
4078 class CAHMapCenter
: public IActionHandler
4080 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
4082 std::string map
= getParam(params
, "map");
4083 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4084 CGroupMap
*gm
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4086 gm
->centerOnPlayer();
4089 REGISTER_ACTION_HANDLER(CAHMapCenter
, "map_center");
4091 //=========================================================================================================
4092 // return to the parent map
4093 class CAHMapBack
: public IActionHandler
4095 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
4097 std::string map
= getParam(params
, "map");
4098 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4099 CGroupMap
*pGM
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4100 if (pGM
== NULL
) return;
4101 SMap
*pMap
= pGM
->getParentMap(pGM
->getCurMap());
4103 pGM
->setMap(pMap
->Name
);
4106 REGISTER_ACTION_HANDLER(CAHMapBack
, "map_back");
4108 //=========================================================================================================
4109 // valid the respawn location selected
4110 class CAHRespawnMapValid
: public IActionHandler
4112 virtual void execute (CCtrlBase
* /* pCaller */, const string
¶ms
)
4114 std::string map
= getParam(params
, "map");
4115 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4116 CGroupMap
*gm
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4118 if (gm
->getRespawnSelected() == -1) return;
4121 const string msgName
= "DEATH:ASK_RESPAWN";
4122 if (!GenericMsgHeaderMngr
.pushNameToStream(msgName
, out
))
4124 nlwarning ("don't know message name %s", msgName
.c_str());
4128 uint16 respawnIndex
= (uint16
)gm
->getRespawnSelected();
4129 out
.serial(respawnIndex
);
4131 //nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), respawnIndex);
4134 Yoyo: NO!!! don't do this!! leave the DB Player MBEHAV Mode drive this (laggy but correct)....
4135 Else Errors arise if the client MBEHAV Mode never reset to Normal==1 (for any lag reason)
4136 The following scenario else could cause a bug:
4137 - the player is dead, the respawn map is activated
4138 - the player click "respawn"
4139 - in the buggy version we close the window immediatly (no lag)
4140 - the server receive the ASK respawn, resapwn the player, and change the mode to NORMAL==1
4141 - the server decide that the PLAYER DIES AUTOMATICALLY in the same server tick (gingo in town for instance! :) )
4142 NB: even if the DIE arise in following frame, lag and packet loss etc... can still cause problems
4143 - the server then reset the mode to DEATH
4144 - the client never receive the change Mode: 0-->1-->0 (always 0), hence the window is not reopened
4145 - the user cannot reswpan....
4146 Instead, I chose to hide the timer text in map.xml
4148 /*sint64 val = NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:CURRENT_SERVER_TICK")->getValue64();
4149 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:RESPAWN:END_DATE")->setValue64(val+10*10);
4150 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:OPEN_RESPAWN_AT_TIME")->setValue64(0);
4151 // must hide the window which contains this map, not the map itself!!
4152 CInterfaceGroup *rootWindow= gm->getRootWindow();
4153 if(rootWindow) rootWindow->setActive(false);
4155 NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:RESPAWN:MSG_SENT")->setValue64(1);
4158 REGISTER_ACTION_HANDLER(CAHRespawnMapValid
, "respawn_map_valid");
4161 //=========================================================================================================
4162 // right click on the map
4163 class CAHWorldMapRightClick
: public IActionHandler
4165 virtual void execute (CCtrlBase
*pCaller
, const string
¶ms
)
4167 std::string map
= getParam(params
, "map");
4168 std::string menu
= getParam(params
, "menu");
4170 hideTeleportButtonsInPopupMenuIfNotEnoughPriv();
4172 CGroupMap
*gm
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId(map
));
4177 if (gm
->getArkPowoMode() == "editor")
4178 menu
= gm
->getArkPowoMapMenu();
4180 menu
= "ui:interface:map_menu_island";
4185 menu
= "ui:interface:map_menu";
4187 // update menu with closest landmarks
4188 NLMISC::CVector2f
pos(NLMISC::CVector2f::Null
);
4189 CCtrlButton
*button
= dynamic_cast<CCtrlButton
*>(pCaller
);
4191 gm
->getLandmarkPosition(button
, pos
);
4193 if(pos
== NLMISC::CVector2f::Null
)
4195 pos
= gm
->getRightClickLastPos();
4196 gm
->mapToWorld(pos
, pos
);
4199 gm
->updateClosestLandMarkMenu(menu
, pos
);
4202 CAHManager::getInstance()->runActionHandler("active_menu", pCaller
, "menu=" + menu
);
4205 REGISTER_ACTION_HANDLER(CAHWorldMapRightClick
, "world_map_right_click")
4207 //=========================================================================================================
4208 // A land mark button has been pushed
4209 class CAHLandMarkTeleport
: public IActionHandler
4211 virtual void execute (CCtrlBase
*pCaller
, const string
&/* params */)
4213 CCtrlButton
*button
= dynamic_cast<CCtrlButton
*>(pCaller
);
4214 if (!button
) return;
4215 // Select the landmark as the current target
4216 CGroupMap
*map
= dynamic_cast<CGroupMap
*>(button
->getParent());
4218 NLMISC::CVector2f pos
;
4219 map
->getLandmarkPosition(button
, pos
);
4221 // Check if the pos is ok
4222 if(pos
== NLMISC::CVector2f::Null
) return;
4224 closeLandMarkNameDialog();
4225 // Remove the selection.
4226 UserEntity
->selection(CLFECOMMON::INVALID_SLOT
);
4227 // Remove the target.
4228 UserEntity
->targetSlot(CLFECOMMON::INVALID_SLOT
);
4230 nlinfo("LM teleport to %f,%f", pos
.x
, pos
.y
);
4231 ICommand::execute(toString("a Position %f,%f", pos
.x
, pos
.y
), *InfoLog
);
4234 REGISTER_ACTION_HANDLER(CAHLandMarkTeleport
, "land_mark_teleport");
4237 //=========================================================================================================
4238 // Teleport player to the given location
4239 class CAHMapTeleport
: public IActionHandler
4241 virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* params */)
4243 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4244 CGroupMap
*clickedMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getCtrlLaunchingModal());
4245 closeLandMarkNameDialog();
4246 NLMISC::CVector2f pos
= clickedMap
->getRightClickLastPos();
4247 clickedMap
->mapToWorld(pos
, pos
);
4248 // Remove the selection.
4249 UserEntity
->selection(CLFECOMMON::INVALID_SLOT
);
4250 // Remove the target.
4251 UserEntity
->targetSlot(CLFECOMMON::INVALID_SLOT
);
4253 nlinfo("teleport to %f,%f", pos
.x
, pos
.y
);
4254 ICommand::execute(toString("a Position %f,%f", pos
.x
, pos
.y
), *InfoLog
);
4258 REGISTER_ACTION_HANDLER(CAHMapTeleport
, "map_teleport");
4260 //=========================================================================================================
4261 // update LandMarks Colors
4262 class CUpdateLandMarksColor
: public IActionHandler
{public: virtual void execute (CCtrlBase
* /* pCaller */, const string
&/* Params */)
4264 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
4266 CUserLandMark::_LandMarksColor
[CUserLandMark::Misc
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:MISC")->getValueRGBA();
4267 CUserLandMark::_LandMarksColor
[CUserLandMark::Tribe
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:TRIBE")->getValueRGBA();
4268 CUserLandMark::_LandMarksColor
[CUserLandMark::Bandit
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:BANDIT")->getValueRGBA();
4269 CUserLandMark::_LandMarksColor
[CUserLandMark::Citizen
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:CITIZEN")->getValueRGBA();
4270 CUserLandMark::_LandMarksColor
[CUserLandMark::Fauna
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FAUNA")->getValueRGBA();
4271 CUserLandMark::_LandMarksColor
[CUserLandMark::FaunaExcel
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FAUNAEXCEL")->getValueRGBA();
4272 CUserLandMark::_LandMarksColor
[CUserLandMark::FaunaSup
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FAUNASUP")->getValueRGBA();
4273 CUserLandMark::_LandMarksColor
[CUserLandMark::Forage
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FORAGE")->getValueRGBA();
4274 CUserLandMark::_LandMarksColor
[CUserLandMark::ForageExcel
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FORAGEEXCEL")->getValueRGBA();
4275 CUserLandMark::_LandMarksColor
[CUserLandMark::ForageSup
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FORAGESUP")->getValueRGBA();
4276 CUserLandMark::_LandMarksColor
[CUserLandMark::Sap
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:SAP")->getValueRGBA();
4277 CUserLandMark::_LandMarksColor
[CUserLandMark::Amber
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:AMBER")->getValueRGBA();
4278 CUserLandMark::_LandMarksColor
[CUserLandMark::Node
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:NODE")->getValueRGBA();
4279 CUserLandMark::_LandMarksColor
[CUserLandMark::Fiber
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FIBER")->getValueRGBA();
4280 CUserLandMark::_LandMarksColor
[CUserLandMark::Bark
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:BARK")->getValueRGBA();
4281 CUserLandMark::_LandMarksColor
[CUserLandMark::Seed
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:SEED")->getValueRGBA();
4282 CUserLandMark::_LandMarksColor
[CUserLandMark::Shell
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:SHELL")->getValueRGBA();
4283 CUserLandMark::_LandMarksColor
[CUserLandMark::Resin
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:RESIN")->getValueRGBA();
4284 CUserLandMark::_LandMarksColor
[CUserLandMark::Wood
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:WOOD")->getValueRGBA();
4285 CUserLandMark::_LandMarksColor
[CUserLandMark::Oil
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:OIL")->getValueRGBA();
4286 CUserLandMark::_LandMarksColor
[CUserLandMark::Mission
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:MISSION")->getValueRGBA();
4287 CUserLandMark::_LandMarksColor
[CUserLandMark::Food
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:FOOD")->getValueRGBA();
4288 CUserLandMark::_LandMarksColor
[CUserLandMark::Construction
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:CONSTRUCTION")->getValueRGBA();
4289 CUserLandMark::_LandMarksColor
[CUserLandMark::Goo
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:GOO")->getValueRGBA();
4290 CUserLandMark::_LandMarksColor
[CUserLandMark::Insect
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:INSECT")->getValueRGBA();
4291 CUserLandMark::_LandMarksColor
[CUserLandMark::Kitin
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:KITIN")->getValueRGBA();
4292 CUserLandMark::_LandMarksColor
[CUserLandMark::Nocive
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:NOCIVE")->getValueRGBA();
4293 CUserLandMark::_LandMarksColor
[CUserLandMark::Preservative
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:PRESERVATIVE")->getValueRGBA();
4294 CUserLandMark::_LandMarksColor
[CUserLandMark::Passage
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:PASSAGE")->getValueRGBA();
4295 CUserLandMark::_LandMarksColor
[CUserLandMark::Teleporter
] = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:LANDMARK:COLORS:TELEPORTER")->getValueRGBA();
4299 CGroupMap
*pGM
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
4300 if (pGM
== NULL
) return;
4301 pGM
->updateUserLandMarks();
4304 REGISTER_ACTION_HANDLER (CUpdateLandMarksColor
, "update_landmarks_color");
4307 ////////////////////
4308 // DEBUG COMMANDS //
4309 ////////////////////
4314 NLMISC_COMMAND( testMapHome
, "Debug : test display of home on map", "" )
4316 if (!args
.empty()) return false;
4317 CInterfaceManager
*im
= CInterfaceManager::getInstance();
4318 NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH
":HOME_POINT")->setValue64((((sint64
) 4787 * 1000) << 32 )| (sint64
) (uint32
) ((sint64
) -3661 * 1000));
4322 NLMISC_COMMAND( testMapRespawn, "Debug : test display of respawn point on map", "" )
4324 if (!args.empty()) return false;
4325 CInterfaceManager *im = CInterfaceManager::getInstance();
4326 NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH ":BIND_POINT")->setValue64((((sint64) 4687 * 1000) << 32 )| (sint64) (uint32) ((sint64) -3561 * 1000));
4330 NLMISC_COMMAND( testRespawn
, "Debug : test respawn map", "" )
4332 if (!args
.empty()) return false;
4334 CRespawnPointsMsg rpm
;
4335 rpm
.NeedToReset
= true;
4336 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(4150*1000,-4350*1000));
4337 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(4640*1000,-4320*1000));
4338 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(4100*1000,-4120*1000));
4339 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(4050*1000,-4200*1000));
4340 rpm
.RespawnPoints
.push_back(CRespawnPointsMsg::SRespawnPoint(4200*1000,-4150*1000));
4341 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
4342 CGroupMap
*pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:respawn_map:content:map_content:actual_map"));
4345 nlwarning("problem cannot find ui:interface:respawn_map:content:map_content:actual_map");
4348 pMap
->addRespawnPoints(rpm
);
4351 pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
4354 nlwarning("problem cannot find ui:interface:map:content:map_content:actual_map");
4357 pMap
->addRespawnPoints(rpm
);
4360 CInterfaceManager *im = CInterfaceManager::getInstance();
4361 NLGUI::CDBManager::getInstance()->getDbProp(COMPASS_DB_PATH ":BIND_POINT")->setValue64((((sint64) 4687 * 1000) << 32 )| (sint64) (uint32) ((sint64) -3561 * 1000));
4366 NLMISC_COMMAND( setMap
, "Debug : test respawn map", "" )
4368 if (args
.size() != 1) return false;
4370 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
4371 CGroupMap
*pMap
= dynamic_cast<CGroupMap
*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
4373 pMap
->setMap(args
[0]);