Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / view_radar.cpp
blobeb50cc664c7799a9dfd07d2decb846c70b83db81
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 Winch Gate Property Limited
3 //
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) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
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/>.
23 // ----------------------------------------------------------------------------
25 #include "stdpch.h"
27 #include "view_radar.h"
28 #include "interface_manager.h"
29 #include "nel/misc/xml_auto_ptr.h"
30 #include "nel/gui/group_container.h"
31 #include "../npc_icon.h"
32 #include "nel/misc/fast_floor.h"
34 #include "../entities.h"
36 // ----------------------------------------------------------------------------
38 using namespace std;
39 using namespace NLMISC;
40 using namespace NL3D;
42 #ifdef DEBUG_NEW
43 #define new DEBUG_NEW
44 #endif
46 extern NL3D::UCamera MainCam;
48 NLMISC_REGISTER_OBJECT(CViewBase, CViewRadar, std::string, "radar");
50 // ----------------------------------------------------------------------------
52 CViewRadar::CViewRadar(const TCtorParam &param)
53 : CViewBase(param)
55 CInterfaceManager *pIM = CInterfaceManager::getInstance();
56 CCDBNodeLeaf *pUIMI = CDBManager::getInstance()->getDbProp( "UI:SAVE:INSCENE:FRIEND:MISSION_ICON" );
57 if (pUIMI)
59 ICDBNode::CTextId textId;
60 pUIMI->addObserver( &_MissionIconsObs, textId);
63 CCDBNodeLeaf *pUIMMI = CDBManager::getInstance()->getDbProp( "UI:SAVE:INSCENE:FRIEND:MINI_MISSION_ICON" );
64 if (pUIMMI)
66 ICDBNode::CTextId textId;
67 pUIMMI->addObserver( &_MiniMissionSpotsObs, textId);
71 bool CViewRadar::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
73 CXMLAutoPtr prop;
75 //try to get props that can be inherited from groups
76 //if a property is not defined, try to find it in the parent group.
77 //if it is undefined, set it to zero
78 if (! CViewBase::parse(cur,parentGroup) )
80 string tmp = string("cannot parse view:")+getId()+", parent:"+parentGroup->getId();
81 nlinfo (tmp.c_str());
82 return false;
85 // World size
86 _WorldSize = 100.0;
87 prop = (char*) xmlGetProp( cur, (xmlChar*)"world_size" );
88 if (prop) fromString((const char*)prop, _WorldSize);
90 // Spot textures
91 CInterfaceManager *pIM = CInterfaceManager::getInstance();
92 CViewRenderer &rVR = *CViewRenderer::getInstance();
94 // Large missions Icons
95 const char *spotTextureNames[NbRadarSpotIds] = { "texture_std", "texture_missionlist", "texture_missionauto", "texture_missionstep" };
97 // Mini missions Icons
98 const char *spotMiniTextureNames[NbRadarSpotIds] = { "texture_std", "mini_texture_missionlist", "mini_texture_missionauto", "mini_texture_missionstep" };
100 for (uint i=0; i!=NbRadarSpotIds; ++i)
102 string txName;
104 // Large missions Icons
105 prop = (char*) xmlGetProp( cur, (xmlChar*)spotTextureNames[i] );
106 if (prop)
108 txName = toLowerAscii((const char *) prop);
110 _SpotDescriptions[i].TextureId.setTexture(txName.c_str());
111 rVR.getTextureSizeFromId (_SpotDescriptions[i].TextureId, _SpotDescriptions[i].TxW, _SpotDescriptions[i].TxH);
113 // Mini missions Icons
114 prop = (char*) xmlGetProp( cur, (xmlChar*)spotMiniTextureNames[i] );
115 if (prop)
117 txName = toLowerAscii((const char *) prop);
119 _SpotDescriptions[i].MiniTextureId.setTexture(txName.c_str());
120 rVR.getTextureSizeFromId (_SpotDescriptions[i].MiniTextureId, _SpotDescriptions[i].MTxW, _SpotDescriptions[i].MTxH);
122 if (i == 0)
123 _SpotDescriptions[i].isMissionSpot = false;
124 else
125 _SpotDescriptions[i].isMissionSpot = true;
128 return true;
131 // ----------------------------------------------------------------------------
132 void CViewRadar::draw ()
134 CInterfaceManager *pIM = CInterfaceManager::getInstance();
135 CViewRenderer &rVR = *CViewRenderer::getInstance();
137 CEntityCL *user = EntitiesMngr.entity(0);
138 if (user == NULL) return;
140 float angle;
141 CVectorD xyzRef = user->pos();
142 if (_UseCamera)
144 CVector projectedFront = MainCam.getMatrix().getJ();
145 if (projectedFront.norm() <= 0.01f)
147 projectedFront = MainCam.getMatrix().getK();
148 projectedFront.z = 0.f;
150 CVector cam = projectedFront.normed();
151 angle = (float)(atan2(cam.y, cam.x) - (Pi / 2.0));
153 else
155 const CVector dir = user->front();
156 angle = (float)(atan2(dir.y, dir.x) - (Pi / 2.0));
159 CMatrix mat;
160 mat.identity();
161 // Scale to transform from world to interface screen
162 mat.scale( CVector((float)(_WReal / _WorldSize), (float)(_HReal / _WorldSize), 1) );
163 // local to user
164 mat.rotateZ(-angle);
165 xyzRef.z = 0;
166 mat.translate(-xyzRef);
168 float maxSqrRadius= (float)sqr(_WorldSize/2);
170 for (sint32 i = 1; i < 256; ++i)
172 CEntityCL *entity = EntitiesMngr.entity(i);
173 if (entity == NULL) continue;
175 // if the entity must not be shown in radar
176 if(!entity->getDisplayInRadar())
177 continue;
179 // get entity pos
180 CVectorD xyz = entity->pos();
182 xyz.z = 0;
183 // if the distance is too big so do not display the entity
184 if ((sqr(xyz.x - xyzRef.x)+sqr(xyz.y - xyzRef.y)) > maxSqrRadius) continue;
186 // Transform the dot
187 xyz = mat * xyz;
189 // Convert to screen
190 sint32 x = OptFastFloor((float)xyz.x);
191 sint32 y = OptFastFloor((float)xyz.y);
193 CRGBA col = entity->getColor();
195 if(getModulateGlobalColor())
196 col.modulateFromColor (col, CWidgetManager::getInstance()->getGlobalColorForContent());
197 else
198 col.A = (uint8)(((sint32)col.A*((sint32)CWidgetManager::getInstance()->getGlobalColorForContent().A+1))>>8);
200 // Select the icon to display and draw it
201 uint spotId = CNPCIconCache::getInstance().getNPCIcon(entity).getSpotId();
202 CRadarSpotDesc spotDesc = _SpotDescriptions[spotId];
204 if (!_MissionIconsObs._displayMissionSpots)
205 spotDesc = _SpotDescriptions[0];
207 if (spotDesc.isMissionSpot)
208 col = CRGBA(255, 255, 255, 255);
210 if (entity->isTarget())
211 spotId = 4; // to make it over other spots
213 // Draw it (and make sure mission icons are drawn over regular dot; caution: don't exceed the render layer range)
214 if (spotDesc.isMissionSpot && _MiniMissionSpotsObs._displayMiniMissionSpots)
215 rVR.drawRotFlipBitmap (_RenderLayer+spotId, _XReal+x-(spotDesc.MTxW/2)+(_WReal/2), _YReal+y-(spotDesc.MTxH/2)+(_HReal/2),
216 spotDesc.MTxW, spotDesc.MTxH, 0, false, spotDesc.MiniTextureId, col );
217 else
218 rVR.drawRotFlipBitmap (_RenderLayer+spotId, _XReal+x-(spotDesc.TxW/2)+(_WReal/2), _YReal+y-(spotDesc.TxH/2)+(_HReal/2),
219 spotDesc.TxW, spotDesc.TxH, 0, false, spotDesc.TextureId, col );
223 // ----------------------------------------------------------------------------
224 void CViewRadar::updateCoords()
226 CViewBase::updateCoords();
229 void CViewRadar::CDBMissionIconqObs::update(ICDBNode *node)
231 _displayMissionSpots = ((CCDBNodeLeaf*)node)->getValueBool();
234 void CViewRadar::CDBMiniMissionSpotsObs::update(ICDBNode *node)
236 _displayMiniMissionSpots = ((CCDBNodeLeaf*)node)->getValueBool();