1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2015 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) 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/>.
23 // ----------------------------------------------------------------------------
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 // ----------------------------------------------------------------------------
39 using namespace NLMISC
;
46 extern NL3D::UCamera MainCam
;
48 NLMISC_REGISTER_OBJECT(CViewBase
, CViewRadar
, std::string
, "radar");
50 // ----------------------------------------------------------------------------
52 CViewRadar::CViewRadar(const TCtorParam
¶m
)
55 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
56 CCDBNodeLeaf
*pUIMI
= CDBManager::getInstance()->getDbProp( "UI:SAVE:INSCENE:FRIEND:MISSION_ICON" );
59 ICDBNode::CTextId textId
;
60 pUIMI
->addObserver( &_MissionIconsObs
, textId
);
63 CCDBNodeLeaf
*pUIMMI
= CDBManager::getInstance()->getDbProp( "UI:SAVE:INSCENE:FRIEND:MINI_MISSION_ICON" );
66 ICDBNode::CTextId textId
;
67 pUIMMI
->addObserver( &_MiniMissionSpotsObs
, textId
);
71 bool CViewRadar::parse(xmlNodePtr cur
, CInterfaceGroup
* parentGroup
)
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();
87 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)"world_size" );
88 if (prop
) fromString((const char*)prop
, _WorldSize
);
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
)
104 // Large missions Icons
105 prop
= (char*) xmlGetProp( cur
, (xmlChar
*)spotTextureNames
[i
] );
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
] );
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
);
123 _SpotDescriptions
[i
].isMissionSpot
= false;
125 _SpotDescriptions
[i
].isMissionSpot
= 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;
141 CVectorD xyzRef
= user
->pos();
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));
155 const CVector dir
= user
->front();
156 angle
= (float)(atan2(dir
.y
, dir
.x
) - (Pi
/ 2.0));
161 // Scale to transform from world to interface screen
162 mat
.scale( CVector((float)(_WReal
/ _WorldSize
), (float)(_HReal
/ _WorldSize
), 1) );
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())
180 CVectorD xyz
= entity
->pos();
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;
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());
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
);
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();