// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // ---------------------------------------------------------------------------- #include "stdpch.h" #include "view_radar.h" #include "interface_manager.h" #include "game_share/xml_auto_ptr.h" #include "group_container.h" #include "../npc_icon.h" #include "nel/misc/fast_floor.h" #include "../entities.h" // ---------------------------------------------------------------------------- using namespace std; using namespace NLMISC; using namespace NL3D; NLMISC_REGISTER_OBJECT(CViewBase, CViewRadar, std::string, "radar"); // ---------------------------------------------------------------------------- bool CViewRadar::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup) { CXMLAutoPtr prop; //try to get props that can be inherited from groups //if a property is not defined, try to find it in the parent group. //if it is undefined, set it to zero if (! CViewBase::parse(cur,parentGroup) ) { string tmp = string("cannot parse view:")+getId()+", parent:"+parentGroup->getId(); nlinfo (tmp.c_str()); return false; } // World size _WorldSize = 100.0; prop = (char*) xmlGetProp( cur, (xmlChar*)"world_size" ); if (prop) fromString((const char*)prop, _WorldSize); // Spot textures CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = pIM->getViewRenderer(); // Large missions Icons const char *spotTextureNames[NbRadarSpotIds] = { "texture_std", "texture_missionlist", "texture_missionauto", "texture_missionstep" }; // Mini missions Icons const char *spotMiniTextureNames[NbRadarSpotIds] = { "texture_std", "mini_texture_missionlist", "mini_texture_missionauto", "mini_texture_missionstep" }; for (uint i=0; i!=NbRadarSpotIds; ++i) { string txName; // Large missions Icons prop = (char*) xmlGetProp( cur, (xmlChar*)spotTextureNames[i] ); if (prop) { txName = (const char *) prop; txName = strlwr (txName); } _SpotDescriptions[i].TextureId.setTexture(txName.c_str()); rVR.getTextureSizeFromId (_SpotDescriptions[i].TextureId, _SpotDescriptions[i].TxW, _SpotDescriptions[i].TxH); // Mini missions Icons prop = (char*) xmlGetProp( cur, (xmlChar*)spotMiniTextureNames[i] ); if (prop) { txName = (const char *) prop; txName = strlwr (txName); } _SpotDescriptions[i].MiniTextureId.setTexture(txName.c_str()); rVR.getTextureSizeFromId (_SpotDescriptions[i].MiniTextureId, _SpotDescriptions[i].MTxW, _SpotDescriptions[i].MTxH); if (i == 0) _SpotDescriptions[i].isMissionSpot = false; else _SpotDescriptions[i].isMissionSpot = true; } return true; } // ---------------------------------------------------------------------------- void CViewRadar::draw () { CInterfaceManager *pIM = CInterfaceManager::getInstance(); CViewRenderer &rVR = pIM->getViewRenderer(); CEntityCL *user = EntitiesMngr.entity(0); if (user == NULL) return; CVectorD xyzRef = user->pos(); CVector dir = user->front(); float angle = (float)(atan2(dir.y, dir.x) - (Pi / 2.0)); CMatrix mat; mat.identity(); // Scale to transform from world to interface screen mat.scale( CVector((float)(_WReal / _WorldSize), (float)(_HReal / _WorldSize), 1) ); // local to user mat.rotateZ(-angle); xyzRef.z = 0; mat.translate(-xyzRef); float maxSqrRadius= (float)sqr(_WorldSize/2); const bool displayMissionSpots = pIM->getDbProp("UI:SAVE:INSCENE:FRIEND:MISSION_ICON")->getValueBool(); const bool displayMiniMissionSpots = pIM->getDbProp("UI:SAVE:INSCENE:FRIEND:MINI_MISSION_ICON")->getValueBool(); for (sint32 i = 1; i < 256; ++i) { CEntityCL *entity = EntitiesMngr.entity(i); if (entity == NULL) continue; // if the entity must not be shown in radar if(!entity->getDisplayInRadar()) continue; // get entity pos CVectorD xyz = entity->pos(); xyz.z = 0; // if the distance is too big so do not display the entity if ((sqr(xyz.x - xyzRef.x)+sqr(xyz.y - xyzRef.y)) > maxSqrRadius) continue; // Transform the dot xyz = mat * xyz; // Convert to screen sint32 x = OptFastFloor((float)xyz.x); sint32 y = OptFastFloor((float)xyz.y); CRGBA col = entity->getColor(); if(getModulateGlobalColor()) col.modulateFromColor (col, pIM->getGlobalColorForContent()); else col.A = (uint8)(((sint32)col.A*((sint32)pIM->getGlobalColorForContent().A+1))>>8); // Select the icon to display and draw it uint spotId = CNPCIconCache::getInstance().getNPCIcon(entity).getSpotId(); CRadarSpotDesc spotDesc = _SpotDescriptions[spotId]; if (!displayMissionSpots) spotDesc = _SpotDescriptions[0]; if (spotDesc.isMissionSpot) col = CRGBA(255, 255, 255, 255); if (entity->isTarget()) spotId = 4; // to make it over other spots // Draw it (and make sure mission icons are drawn over regular dot; caution: don't exceed the render layer range) if (spotDesc.isMissionSpot && displayMiniMissionSpots) rVR.drawRotFlipBitmap (_RenderLayer+spotId, _XReal+x-(spotDesc.MTxW/2)+(_WReal/2), _YReal+y-(spotDesc.MTxH/2)+(_HReal/2), spotDesc.MTxW, spotDesc.MTxH, 0, false, spotDesc.MiniTextureId, col ); else rVR.drawRotFlipBitmap (_RenderLayer+spotId, _XReal+x-(spotDesc.TxW/2)+(_WReal/2), _YReal+y-(spotDesc.TxH/2)+(_HReal/2), spotDesc.TxW, spotDesc.TxH, 0, false, spotDesc.TextureId, col ); } } // ---------------------------------------------------------------------------- void CViewRadar::updateCoords() { CViewBase::updateCoords(); }