llfloaterworldmap.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:41k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llfloaterworldmap.cpp
  3.  * @author James Cook, Tom Yedwab
  4.  * @brief LLFloaterWorldMap class implementation
  5.  *
  6.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  7.  * 
  8.  * Copyright (c) 2003-2010, Linden Research, Inc.
  9.  * 
  10.  * Second Life Viewer Source Code
  11.  * The source code in this file ("Source Code") is provided by Linden Lab
  12.  * to you under the terms of the GNU General Public License, version 2.0
  13.  * ("GPL"), unless you have obtained a separate licensing agreement
  14.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  15.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  16.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  17.  * 
  18.  * There are special exceptions to the terms and conditions of the GPL as
  19.  * it is applied to this Source Code. View the full text of the exception
  20.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  21.  * online at
  22.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  23.  * 
  24.  * By copying, modifying or distributing this software, you acknowledge
  25.  * that you have read and understood your obligations described above,
  26.  * and agree to abide by those obligations.
  27.  * 
  28.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  29.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  30.  * COMPLETENESS OR PERFORMANCE.
  31.  * $/LicenseInfo$
  32.  */
  33. /*
  34.  * Map of the entire world, with multiple background images,
  35.  * avatar tracking, teleportation by double-click, etc.
  36.  */
  37. #include "llviewerprecompiledheaders.h"
  38. #include "llfloaterworldmap.h"
  39. #include "llagent.h"
  40. #include "llbutton.h"
  41. #include "llcallingcard.h"
  42. #include "llcombobox.h"
  43. #include "llviewercontrol.h"
  44. #include "llcommandhandler.h"
  45. #include "lldraghandle.h"
  46. //#include "llfirstuse.h"
  47. #include "llfloaterreg.h" // getTypedInstance()
  48. #include "llfocusmgr.h"
  49. #include "llinventorymodel.h"
  50. #include "llinventoryobserver.h"
  51. #include "lllandmarklist.h"
  52. #include "lllineeditor.h"
  53. #include "llnotificationsutil.h"
  54. #include "llregionhandle.h"
  55. #include "llscrolllistctrl.h"
  56. #include "llslurl.h"
  57. #include "lltextbox.h"
  58. #include "lltracker.h"
  59. #include "lltrans.h"
  60. #include "llviewerinventory.h" // LLViewerInventoryItem
  61. #include "llviewermenu.h"
  62. #include "llviewerregion.h"
  63. #include "llviewerstats.h"
  64. #include "llviewertexture.h"
  65. #include "llworldmap.h"
  66. #include "llworldmapmessage.h"
  67. #include "llworldmapview.h"
  68. #include "lluictrlfactory.h"
  69. #include "llappviewer.h"
  70. #include "llmapimagetype.h"
  71. #include "llweb.h"
  72. #include "llslider.h"
  73. #include "message.h"
  74. #include "llwindow.h" // copyTextToClipboard()
  75. //---------------------------------------------------------------------------
  76. // Constants
  77. //---------------------------------------------------------------------------
  78. static const F32 MAP_ZOOM_TIME = 0.2f;
  79. // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
  80. // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
  81. // sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
  82. // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
  83. static const S32 MAX_VISIBLE_REGIONS = 512;
  84. enum EPanDirection
  85. {
  86. PAN_UP,
  87. PAN_DOWN,
  88. PAN_LEFT,
  89. PAN_RIGHT
  90. };
  91. // Values in pixels per region
  92. static const F32 ZOOM_MAX = 128.f;
  93. //---------------------------------------------------------------------------
  94. // Globals
  95. //---------------------------------------------------------------------------
  96. // handle secondlife:///app/worldmap/{NAME}/{COORDS} URLs
  97. class LLWorldMapHandler : public LLCommandHandler
  98. {
  99. public:
  100. // requires trusted browser to trigger
  101. LLWorldMapHandler() : LLCommandHandler("worldmap", UNTRUSTED_THROTTLE) { }
  102. bool handle(const LLSD& params, const LLSD& query_map,
  103. LLMediaCtrl* web)
  104. {
  105. if (params.size() == 0)
  106. {
  107. // support the secondlife:///app/worldmap SLapp
  108. LLFloaterReg::showInstance("world_map", "center");
  109. return true;
  110. }
  111. // support the secondlife:///app/worldmap/{LOCATION}/{COORDS} SLapp
  112. const std::string region_name = params[0].asString();
  113. S32 x = (params.size() > 1) ? params[1].asInteger() : 128;
  114. S32 y = (params.size() > 2) ? params[2].asInteger() : 128;
  115. S32 z = (params.size() > 3) ? params[3].asInteger() : 0;
  116. LLFloaterWorldMap::getInstance()->trackURL(region_name, x, y, z);
  117. LLFloaterReg::showInstance("world_map", "center");
  118. return true;
  119. }
  120. };
  121. LLWorldMapHandler gWorldMapHandler;
  122. LLFloaterWorldMap* gFloaterWorldMap = NULL;
  123. class LLMapInventoryObserver : public LLInventoryObserver
  124. {
  125. public:
  126. LLMapInventoryObserver() {}
  127. virtual ~LLMapInventoryObserver() {}
  128. virtual void changed(U32 mask);
  129. };
  130.   
  131. void LLMapInventoryObserver::changed(U32 mask)
  132. {
  133. // if there's a change we're interested in.
  134. if((mask & (LLInventoryObserver::CALLING_CARD | LLInventoryObserver::ADD |
  135. LLInventoryObserver::REMOVE)) != 0)
  136. {
  137. gFloaterWorldMap->inventoryChanged();
  138. }
  139. }
  140. class LLMapFriendObserver : public LLFriendObserver
  141. {
  142. public:
  143. LLMapFriendObserver() {}
  144. virtual ~LLMapFriendObserver() {}
  145. virtual void changed(U32 mask);
  146. };
  147. void LLMapFriendObserver::changed(U32 mask)
  148. {
  149. // if there's a change we're interested in.
  150. if((mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE | LLFriendObserver::POWERS)) != 0)
  151. {
  152. gFloaterWorldMap->friendsChanged();
  153. }
  154. }
  155. //---------------------------------------------------------------------------
  156. // Statics
  157. //---------------------------------------------------------------------------
  158. // Used as a pretend asset and inventory id to mean "landmark at my home location."
  159. const LLUUID LLFloaterWorldMap::sHomeID( "10000000-0000-0000-0000-000000000001" );
  160. //---------------------------------------------------------------------------
  161. // Construction and destruction
  162. //---------------------------------------------------------------------------
  163. LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
  164. : LLFloater(key),
  165. mInventory(NULL),
  166. mInventoryObserver(NULL),
  167. mFriendObserver(NULL),
  168. mCompletingRegionName(),
  169. mCompletingRegionPos(),
  170. mWaitingForTracker(FALSE),
  171. mIsClosing(FALSE),
  172. mSetToUserPosition(TRUE),
  173. mTrackedLocation(0,0,0),
  174. mTrackedStatus(LLTracker::TRACKING_NOTHING)
  175. {
  176. gFloaterWorldMap = this;
  177. mFactoryMap["objects_mapview"] = LLCallbackMap(createWorldMapView, NULL);
  178. //Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this, "floater_world_map.xml", FALSE);
  179. mCommitCallbackRegistrar.add("WMap.Location", boost::bind(&LLFloaterWorldMap::onLocationCommit, this));
  180. mCommitCallbackRegistrar.add("WMap.AvatarCombo", boost::bind(&LLFloaterWorldMap::onAvatarComboCommit, this));
  181. mCommitCallbackRegistrar.add("WMap.Landmark", boost::bind(&LLFloaterWorldMap::onLandmarkComboCommit, this));
  182. mCommitCallbackRegistrar.add("WMap.SearchResult", boost::bind(&LLFloaterWorldMap::onCommitSearchResult, this));
  183. mCommitCallbackRegistrar.add("WMap.GoHome", boost::bind(&LLFloaterWorldMap::onGoHome, this));
  184. mCommitCallbackRegistrar.add("WMap.Teleport", boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
  185. mCommitCallbackRegistrar.add("WMap.ShowTarget", boost::bind(&LLFloaterWorldMap::onShowTargetBtn, this));
  186. mCommitCallbackRegistrar.add("WMap.ShowAgent", boost::bind(&LLFloaterWorldMap::onShowAgentBtn, this));
  187. mCommitCallbackRegistrar.add("WMap.Clear", boost::bind(&LLFloaterWorldMap::onClearBtn, this));
  188. mCommitCallbackRegistrar.add("WMap.CopySLURL", boost::bind(&LLFloaterWorldMap::onCopySLURL, this));
  189. }
  190. // static
  191. void* LLFloaterWorldMap::createWorldMapView(void* data)
  192. {
  193. return new LLWorldMapView();
  194. }
  195. BOOL LLFloaterWorldMap::postBuild()
  196. {
  197. mPanel = getChild<LLPanel>("objects_mapview");
  198. LLComboBox *avatar_combo = getChild<LLComboBox>("friend combo");
  199. if (avatar_combo)
  200. {
  201. avatar_combo->selectFirstItem();
  202. avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) );
  203. avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
  204. }
  205. getChild<LLScrollListCtrl>("location")->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
  206. LLLineEditor *location_editor = getChild<LLLineEditor>("location");
  207. if (location_editor)
  208. {
  209. location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this, _1), NULL );
  210. }
  211. getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
  212. LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");
  213. if (landmark_combo)
  214. {
  215. landmark_combo->selectFirstItem();
  216. landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) );
  217. landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
  218. }
  219. mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f);
  220. childSetValue("zoom slider", LLWorldMapView::sMapScale);
  221. setDefaultBtn(NULL);
  222. mZoomTimer.stop();
  223. return TRUE;
  224. }
  225. // virtual
  226. LLFloaterWorldMap::~LLFloaterWorldMap()
  227. {
  228. // All cleaned up by LLView destructor
  229. mPanel = NULL;
  230. // Inventory deletes all observers on shutdown
  231. mInventory = NULL;
  232. mInventoryObserver = NULL;
  233. // avatar tracker will delete this for us.
  234. mFriendObserver = NULL;
  235. gFloaterWorldMap = NULL;
  236. }
  237. //static
  238. LLFloaterWorldMap* LLFloaterWorldMap::getInstance()
  239. {
  240. return LLFloaterReg::getTypedInstance<LLFloaterWorldMap>("world_map");
  241. }
  242. // virtual
  243. void LLFloaterWorldMap::onClose(bool app_quitting)
  244. {
  245. // While we're not visible, discard the overlay images we're using
  246. LLWorldMap::getInstance()->clearImageRefs();
  247. }
  248. // virtual
  249. void LLFloaterWorldMap::onOpen(const LLSD& key)
  250. {
  251. bool center_on_target = (key.asString() == "center");
  252. mIsClosing = FALSE;
  253. LLWorldMapView* map_panel;
  254. map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel;
  255. map_panel->clearLastClick();
  256. {
  257. // reset pan on show, so it centers on you again
  258. if (!center_on_target)
  259. {
  260. LLWorldMapView::setPan(0, 0, TRUE);
  261. }
  262. map_panel->updateVisibleBlocks();
  263. // Reload items as they may have changed
  264. LLWorldMap::getInstance()->reloadItems();
  265. // We may already have a bounding box for the regions of the world,
  266. // so use that to adjust the view.
  267. adjustZoomSliderBounds();
  268. // Could be first show
  269. //LLFirstUse::useMap();
  270. // Start speculative download of landmarks
  271. const LLUUID landmark_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
  272. gInventory.startBackgroundFetch(landmark_folder_id);
  273. childSetFocus("location", TRUE);
  274. gFocusMgr.triggerFocusFlash();
  275. buildAvatarIDList();
  276. buildLandmarkIDLists();
  277. // If nothing is being tracked, set flag so the user position will be found
  278. mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
  279. }
  280. if (center_on_target)
  281. {
  282. centerOnTarget(FALSE);
  283. }
  284. }
  285. // static
  286. void LLFloaterWorldMap::reloadIcons(void*)
  287. {
  288. LLWorldMap::getInstance()->reloadItems();
  289. }
  290. // virtual
  291. BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask)
  292. {
  293. BOOL handled;
  294. handled = LLFloater::handleHover(x, y, mask);
  295. return handled;
  296. }
  297. BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks)
  298. {
  299. if (!isMinimized() && isFrontmost())
  300. {
  301. LLRect area;
  302. childGetRect("search_results", area);
  303. if(!area.pointInRect(x, y))
  304. {
  305. F32 slider_value = (F32)childGetValue("zoom slider").asReal();
  306. slider_value += ((F32)clicks * -0.3333f);
  307. childSetValue("zoom slider", LLSD(slider_value));
  308. return TRUE;
  309. }
  310. }
  311. return LLFloater::handleScrollWheel(x, y, clicks);
  312. }
  313. // virtual
  314. void LLFloaterWorldMap::reshape( S32 width, S32 height, BOOL called_from_parent )
  315. {
  316. LLFloater::reshape( width, height, called_from_parent );
  317. }
  318. // virtual
  319. void LLFloaterWorldMap::draw()
  320. {
  321. static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
  322. static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
  323. // Hide/Show Mature Events controls
  324. childSetVisible("events_mature_icon", gAgent.canAccessMature());
  325. childSetVisible("events_mature_label", gAgent.canAccessMature());
  326. childSetVisible("event_mature_chk", gAgent.canAccessMature());
  327. childSetVisible("events_adult_icon", gAgent.canAccessMature());
  328. childSetVisible("events_adult_label", gAgent.canAccessMature());
  329. childSetVisible("event_adult_chk", gAgent.canAccessMature());
  330. bool adult_enabled = gAgent.canAccessAdult();
  331. if (!adult_enabled)
  332. {
  333. childSetValue("event_adult_chk", FALSE);
  334. }
  335. childSetEnabled("event_adult_chk", adult_enabled);
  336. // On orientation island, users don't have a home location yet, so don't
  337. // let them teleport "home".  It dumps them in an often-crowed welcome
  338. // area (infohub) and they get confused. JC
  339. LLViewerRegion* regionp = gAgent.getRegion();
  340. bool agent_on_prelude = (regionp && regionp->isPrelude());
  341. bool enable_go_home = gAgent.isGodlike() || !agent_on_prelude;
  342. childSetEnabled("Go Home", enable_go_home);
  343. updateLocation();
  344. LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); 
  345. if (LLTracker::TRACKING_AVATAR == tracking_status)
  346. {
  347. childSetColor("avatar_icon", map_track_color);
  348. }
  349. else
  350. {
  351. childSetColor("avatar_icon", map_track_disabled_color);
  352. }
  353. if (LLTracker::TRACKING_LANDMARK == tracking_status)
  354. {
  355. childSetColor("landmark_icon", map_track_color);
  356. }
  357. else
  358. {
  359. childSetColor("landmark_icon", map_track_disabled_color);
  360. }
  361. if (LLTracker::TRACKING_LOCATION == tracking_status)
  362. {
  363. childSetColor("location_icon", map_track_color);
  364. }
  365. else
  366. {
  367. if (mCompletingRegionName != "")
  368. {
  369. F64 seconds = LLTimer::getElapsedSeconds();
  370. double value = fmod(seconds, 2);
  371. value = 0.5 + 0.5*cos(value * F_PI);
  372. LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
  373. childSetColor("location_icon", loading_color);
  374. }
  375. else
  376. {
  377. childSetColor("location_icon", map_track_disabled_color);
  378. }
  379. }
  380. // check for completion of tracking data
  381. if (mWaitingForTracker)
  382. {
  383. centerOnTarget(TRUE);
  384. }
  385. childSetEnabled("Teleport", (BOOL)tracking_status);
  386. // childSetEnabled("Clear", (BOOL)tracking_status);
  387. childSetEnabled("Show Destination", (BOOL)tracking_status || LLWorldMap::getInstance()->isTracking());
  388. childSetEnabled("copy_slurl", (mSLURL.size() > 0) );
  389. setMouseOpaque(TRUE);
  390. getDragHandle()->setMouseOpaque(TRUE);
  391. //RN: snaps to zoom value because interpolation caused jitter in the text rendering
  392. if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)childGetValue("zoom slider").asReal())
  393. {
  394. mZoomTimer.start();
  395. }
  396. F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME;
  397. if (interp > 1.f)
  398. {
  399. interp = 1.f;
  400. mZoomTimer.stop();
  401. }
  402. mCurZoomVal = lerp(mCurZoomVal, (F32)childGetValue("zoom slider").asReal(), interp);
  403. F32 map_scale = 256.f*pow(2.f, mCurZoomVal);
  404. LLWorldMapView::setScale( map_scale );
  405. // Enable/disable checkboxes depending on the zoom level
  406. // If above threshold level (i.e. low res) -> Disable all checkboxes
  407. // If under threshold level (i.e. high res) -> Enable all checkboxes
  408. bool enable = LLWorldMapView::showRegionInfo();
  409. childSetEnabled("people_chk", enable);
  410. childSetEnabled("infohub_chk", enable);
  411. childSetEnabled("telehub_chk", enable);
  412. childSetEnabled("land_for_sale_chk", enable);
  413. childSetEnabled("event_chk", enable);
  414. childSetEnabled("event_mature_chk", enable);
  415. childSetEnabled("event_adult_chk", enable);
  416. LLFloater::draw();
  417. }
  418. //-------------------------------------------------------------------------
  419. // Internal utility functions
  420. //-------------------------------------------------------------------------
  421. void LLFloaterWorldMap::trackAvatar( const LLUUID& avatar_id, const std::string& name )
  422. {
  423. LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
  424. if (!iface) return;
  425. buildAvatarIDList();
  426. if(iface->setCurrentByID(avatar_id) || gAgent.isGodlike())
  427. {
  428. // *HACK: Adjust Z values automatically for liaisons & gods so
  429. // they swoop down when they click on the map. Requested
  430. // convenience.
  431. if(gAgent.isGodlike())
  432. {
  433. childSetValue("spin z", LLSD(200.f));
  434. }
  435. // Don't re-request info if we already have it or we won't have it in time to teleport
  436. if (mTrackedStatus != LLTracker::TRACKING_AVATAR || name != mTrackedAvatarName)
  437. {
  438. mTrackedStatus = LLTracker::TRACKING_AVATAR;
  439. mTrackedAvatarName = name;
  440. LLTracker::trackAvatar(avatar_id, name);
  441. }
  442. }
  443. else
  444. {
  445. LLTracker::stopTracking(NULL);
  446. }
  447. setDefaultBtn("Teleport");
  448. }
  449. void LLFloaterWorldMap::trackLandmark( const LLUUID& landmark_item_id )
  450. {
  451. LLCtrlSelectionInterface *iface = childGetSelectionInterface("landmark combo");
  452. if (!iface) return;
  453. buildLandmarkIDLists();
  454. BOOL found = FALSE;
  455. S32 idx;
  456. for (idx = 0; idx < mLandmarkItemIDList.count(); idx++)
  457. {
  458. if ( mLandmarkItemIDList.get(idx) == landmark_item_id)
  459. {
  460. found = TRUE;
  461. break;
  462. }
  463. }
  464. if (found && iface->setCurrentByID( landmark_item_id ) ) 
  465. {
  466. LLUUID asset_id = mLandmarkAssetIDList.get( idx );
  467. std::string name;
  468. LLComboBox* combo = getChild<LLComboBox>( "landmark combo");
  469. if (combo) name = combo->getSimple();
  470. mTrackedStatus = LLTracker::TRACKING_LANDMARK;
  471. LLTracker::trackLandmark(mLandmarkAssetIDList.get( idx ), // assetID
  472. mLandmarkItemIDList.get( idx ), // itemID
  473. name); // name
  474. if( asset_id != sHomeID )
  475. {
  476. // start the download process
  477. gLandmarkList.getAsset( asset_id);
  478. }
  479. // We have to download both region info and landmark data, so set busy. JC
  480. // getWindow()->incBusyCount();
  481. }
  482. else
  483. {
  484. LLTracker::stopTracking(NULL);
  485. }
  486. setDefaultBtn("Teleport");
  487. }
  488. void LLFloaterWorldMap::trackEvent(const LLItemInfo &event_info)
  489. {
  490. mTrackedStatus = LLTracker::TRACKING_LOCATION;
  491. LLTracker::trackLocation(event_info.getGlobalPosition(), event_info.getName(), event_info.getToolTip(), LLTracker::LOCATION_EVENT);
  492. setDefaultBtn("Teleport");
  493. }
  494. void LLFloaterWorldMap::trackGenericItem(const LLItemInfo &item)
  495. {
  496. mTrackedStatus = LLTracker::TRACKING_LOCATION;
  497. LLTracker::trackLocation(item.getGlobalPosition(), item.getName(), item.getToolTip(), LLTracker::LOCATION_ITEM);
  498. setDefaultBtn("Teleport");
  499. }
  500. void LLFloaterWorldMap::trackLocation(const LLVector3d& pos_global)
  501. {
  502. LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
  503. if (!sim_info)
  504. {
  505. // We haven't found a region for that point yet, leave the tracking to the world map
  506. LLWorldMap::getInstance()->setTracking(pos_global);
  507. LLTracker::stopTracking(NULL);
  508. S32 world_x = S32(pos_global.mdV[0] / 256);
  509. S32 world_y = S32(pos_global.mdV[1] / 256);
  510. LLWorldMapMessage::getInstance()->sendMapBlockRequest(world_x, world_y, world_x, world_y, true);
  511. setDefaultBtn("");
  512. return;
  513. }
  514. if (sim_info->isDown())
  515. {
  516. // Down region. Show the blue circle of death!
  517. // i.e. let the world map that this and tell it it's invalid
  518. LLWorldMap::getInstance()->setTracking(pos_global);
  519. LLWorldMap::getInstance()->setTrackingInvalid();
  520. LLTracker::stopTracking(NULL);
  521. setDefaultBtn("");
  522. return;
  523. }
  524. std::string sim_name = sim_info->getName();
  525. F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
  526. F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
  527. std::string full_name = llformat("%s (%d, %d, %d)", 
  528.   sim_name.c_str(), 
  529.   llround(region_x), 
  530.   llround(region_y),
  531.   llround((F32)pos_global.mdV[VZ]));
  532. std::string tooltip("");
  533. mTrackedStatus = LLTracker::TRACKING_LOCATION;
  534. LLTracker::trackLocation(pos_global, full_name, tooltip);
  535. LLWorldMap::getInstance()->cancelTracking(); // The floater is taking over the tracking
  536. setDefaultBtn("Teleport");
  537. }
  538. void LLFloaterWorldMap::updateLocation()
  539. {
  540. bool gotSimName;
  541. LLTracker::ETrackingStatus status = LLTracker::getTrackingStatus();
  542. // These values may get updated by a message, so need to check them every frame
  543. // The fields may be changed by the user, so only update them if the data changes
  544. LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
  545. if (pos_global.isExactlyZero())
  546. {
  547. LLVector3d agentPos = gAgent.getPositionGlobal();
  548. // Set to avatar's current postion if nothing is selected
  549. if ( status == LLTracker::TRACKING_NOTHING && mSetToUserPosition )
  550. {
  551. // Make sure we know where we are before setting the current user position
  552. std::string agent_sim_name;
  553. gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( agentPos, agent_sim_name );
  554. if ( gotSimName )
  555. {
  556. mSetToUserPosition = FALSE;
  557. // Fill out the location field
  558. childSetValue("location", agent_sim_name);
  559. // Figure out where user is
  560. LLVector3d agentPos = gAgent.getPositionGlobal();
  561. S32 agent_x = llround( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) );
  562. S32 agent_y = llround( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) );
  563. S32 agent_z = llround( (F32)agentPos.mdV[VZ] );
  564. // Set the current SLURL
  565. mSLURL = LLSLURL::buildSLURL(agent_sim_name, agent_x, agent_y, agent_z);
  566. }
  567. }
  568. return; // invalid location
  569. }
  570. std::string sim_name;
  571. gotSimName = LLWorldMap::getInstance()->simNameFromPosGlobal( pos_global, sim_name );
  572. if ((status != LLTracker::TRACKING_NOTHING) &&
  573. (status != mTrackedStatus || pos_global != mTrackedLocation || sim_name != mTrackedSimName))
  574. {
  575. mTrackedStatus = status;
  576. mTrackedLocation = pos_global;
  577. mTrackedSimName = sim_name;
  578. if (status == LLTracker::TRACKING_AVATAR)
  579. {
  580. // *HACK: Adjust Z values automatically for liaisons &
  581. // gods so they swoop down when they click on the
  582. // map. Requested convenience.
  583. if(gAgent.isGodlike())
  584. {
  585. pos_global[2] = 200;
  586. }
  587. }
  588. childSetValue("location", sim_name);
  589. F32 region_x = (F32)fmod( pos_global.mdV[VX], (F64)REGION_WIDTH_METERS );
  590. F32 region_y = (F32)fmod( pos_global.mdV[VY], (F64)REGION_WIDTH_METERS );
  591. // simNameFromPosGlobal can fail, so don't give the user an invalid SLURL
  592. if ( gotSimName )
  593. {
  594. mSLURL = LLSLURL::buildSLURL(sim_name, llround(region_x), llround(region_y), llround((F32)pos_global.mdV[VZ]));
  595. }
  596. else
  597. { // Empty SLURL will disable the "Copy SLURL to clipboard" button
  598. mSLURL = "";
  599. }
  600. }
  601. }
  602. void LLFloaterWorldMap::trackURL(const std::string& region_name, S32 x_coord, S32 y_coord, S32 z_coord)
  603. {
  604. LLSimInfo* sim_info = LLWorldMap::getInstance()->simInfoFromName(region_name);
  605. z_coord = llclamp(z_coord, 0, 4096);
  606. if (sim_info)
  607. {
  608. LLVector3 local_pos;
  609. local_pos.mV[VX] = (F32)x_coord;
  610. local_pos.mV[VY] = (F32)y_coord;
  611. local_pos.mV[VZ] = (F32)z_coord;
  612. LLVector3d global_pos = sim_info->getGlobalPos(local_pos);
  613. trackLocation(global_pos);
  614. setDefaultBtn("Teleport");
  615. }
  616. else
  617. {
  618. // fill in UI based on URL
  619. gFloaterWorldMap->childSetValue("location", region_name);
  620. // Save local coords to highlight position after region global
  621. // position is returned.
  622. gFloaterWorldMap->mCompletingRegionPos.set(
  623. (F32)x_coord, (F32)y_coord, (F32)z_coord);
  624. // pass sim name to combo box
  625. gFloaterWorldMap->mCompletingRegionName = region_name;
  626. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name);
  627. LLStringUtil::toLower(gFloaterWorldMap->mCompletingRegionName);
  628. LLWorldMap::getInstance()->setTrackingCommit();
  629. }
  630. }
  631. void LLFloaterWorldMap::observeInventory(LLInventoryModel* model)
  632. {
  633. if(mInventory)
  634. {
  635. mInventory->removeObserver(mInventoryObserver);
  636. delete mInventoryObserver;
  637. mInventory = NULL;
  638. mInventoryObserver = NULL;
  639. }
  640. if(model)
  641. {
  642. mInventory = model;
  643. mInventoryObserver = new LLMapInventoryObserver;
  644. // Inventory deletes all observers on shutdown
  645. mInventory->addObserver(mInventoryObserver);
  646. inventoryChanged();
  647. }
  648. }
  649. void LLFloaterWorldMap::inventoryChanged()
  650. {
  651. if(!LLTracker::getTrackedLandmarkItemID().isNull())
  652. {
  653. LLUUID item_id = LLTracker::getTrackedLandmarkItemID();
  654. buildLandmarkIDLists();
  655. trackLandmark(item_id);
  656. }
  657. }
  658. void LLFloaterWorldMap::observeFriends()
  659. {
  660. if(!mFriendObserver)
  661. {
  662. mFriendObserver = new LLMapFriendObserver;
  663. LLAvatarTracker::instance().addObserver(mFriendObserver);
  664. friendsChanged();
  665. }
  666. }
  667. void LLFloaterWorldMap::friendsChanged()
  668. {
  669. LLAvatarTracker& t = LLAvatarTracker::instance();
  670. const LLUUID& avatar_id = t.getAvatarID();
  671. buildAvatarIDList();
  672. if(avatar_id.notNull())
  673. {
  674. LLCtrlSelectionInterface *iface = childGetSelectionInterface("friend combo");
  675. const LLRelationship* buddy_info = t.getBuddyInfo(avatar_id);
  676. if(!iface ||
  677.    !iface->setCurrentByID(avatar_id) || 
  678.    (buddy_info && !buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)) ||
  679.    gAgent.isGodlike())
  680. {
  681. LLTracker::stopTracking(NULL);
  682. }
  683. }
  684. }
  685. // No longer really builds a list.  Instead, just updates mAvatarCombo.
  686. void LLFloaterWorldMap::buildAvatarIDList()
  687. {
  688. LLCtrlListInterface *list = childGetListInterface("friend combo");
  689. if (!list) return;
  690.     // Delete all but the "None" entry
  691. S32 list_size = list->getItemCount();
  692. if (list_size > 1)
  693. {
  694. list->selectItemRange(1, -1);
  695. list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
  696. }
  697. // Get all of the calling cards for avatar that are currently online
  698. LLCollectMappableBuddies collector;
  699. LLAvatarTracker::instance().applyFunctor(collector);
  700. LLCollectMappableBuddies::buddy_map_t::iterator it;
  701. LLCollectMappableBuddies::buddy_map_t::iterator end;
  702. it = collector.mMappable.begin();
  703. end = collector.mMappable.end();
  704. for( ; it != end; ++it)
  705. {
  706. list->addSimpleElement((*it).first, ADD_BOTTOM, (*it).second);
  707. }
  708. list->setCurrentByID( LLAvatarTracker::instance().getAvatarID() );
  709. list->selectFirstItem();
  710. }
  711. void LLFloaterWorldMap::buildLandmarkIDLists()
  712. {
  713. LLCtrlListInterface *list = childGetListInterface("landmark combo");
  714. if (!list) return;
  715.     // Delete all but the "None" entry
  716. S32 list_size = list->getItemCount();
  717. if (list_size > 1)
  718. {
  719. list->selectItemRange(1, -1);
  720. list->operateOnSelection(LLCtrlListInterface::OP_DELETE);
  721. }
  722. mLandmarkItemIDList.reset();
  723. mLandmarkAssetIDList.reset();
  724. // Get all of the current landmarks
  725. mLandmarkAssetIDList.put( LLUUID::null );
  726. mLandmarkItemIDList.put( LLUUID::null );
  727. mLandmarkAssetIDList.put( sHomeID );
  728. mLandmarkItemIDList.put( sHomeID );
  729. LLInventoryModel::cat_array_t cats;
  730. LLInventoryModel::item_array_t items;
  731. LLIsType is_landmark(LLAssetType::AT_LANDMARK);
  732. gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
  733. cats,
  734. items,
  735. LLInventoryModel::EXCLUDE_TRASH,
  736. is_landmark);
  737. std::sort(items.begin(), items.end(), LLViewerInventoryItem::comparePointers());
  738. S32 count = items.count();
  739. for(S32 i = 0; i < count; ++i)
  740. {
  741. LLInventoryItem* item = items.get(i);
  742. list->addSimpleElement(item->getName(), ADD_BOTTOM, item->getUUID());
  743. mLandmarkAssetIDList.put( item->getAssetUUID() );
  744. mLandmarkItemIDList.put( item->getUUID() );
  745. }
  746. list->selectFirstItem();
  747. }
  748. F32 LLFloaterWorldMap::getDistanceToDestination(const LLVector3d &destination, 
  749. F32 z_attenuation) const
  750. {
  751. LLVector3d delta = destination - gAgent.getPositionGlobal();
  752. // by attenuating the z-component we effectively 
  753. // give more weight to the x-y plane
  754. delta.mdV[VZ] *= z_attenuation;
  755. F32 distance = (F32)delta.magVec();
  756. return distance;
  757. }
  758. void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
  759. {
  760. LLCtrlListInterface *list = childGetListInterface("search_results");
  761. if (list)
  762. {
  763. list->operateOnAll(LLCtrlListInterface::OP_DELETE);
  764. }
  765. LLWorldMap::getInstance()->cancelTracking();
  766. mCompletingRegionName = "";
  767. }
  768. void LLFloaterWorldMap::clearLandmarkSelection(BOOL clear_ui)
  769. {
  770. if (clear_ui || !childHasKeyboardFocus("landmark combo"))
  771. {
  772. LLCtrlListInterface *list = childGetListInterface("landmark combo");
  773. if (list)
  774. {
  775. list->selectByValue( "None" );
  776. }
  777. }
  778. }
  779. void LLFloaterWorldMap::clearAvatarSelection(BOOL clear_ui)
  780. {
  781. if (clear_ui || !childHasKeyboardFocus("friend combo"))
  782. {
  783. mTrackedStatus = LLTracker::TRACKING_NOTHING;
  784. LLCtrlListInterface *list = childGetListInterface("friend combo");
  785. if (list)
  786. {
  787. list->selectByValue( "None" );
  788. }
  789. }
  790. }
  791. // Adjust the maximally zoomed out limit of the zoom slider so you
  792. // can see the whole world, plus a little.
  793. void LLFloaterWorldMap::adjustZoomSliderBounds()
  794. {
  795. // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed
  796. // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across
  797. // sessions and doesn't prevent the user to pan the world if it was to grow a lot beyond that limit.
  798. // Currently (01/26/09), this value allows the whole grid to be visible in a 1024x1024 window.
  799. S32 world_width_regions  = MAX_VISIBLE_REGIONS;
  800. S32 world_height_regions = MAX_VISIBLE_REGIONS;
  801. // Find how much space we have to display the world
  802. LLWorldMapView* map_panel;
  803. map_panel = (LLWorldMapView*)mPanel;
  804. LLRect view_rect = map_panel->getRect();
  805. // View size in pixels
  806. S32 view_width = view_rect.getWidth();
  807. S32 view_height = view_rect.getHeight();
  808. // Pixels per region to display entire width/height
  809. F32 width_pixels_per_region = (F32) view_width / (F32) world_width_regions;
  810. F32 height_pixels_per_region = (F32) view_height / (F32) world_height_regions;
  811. F32 pixels_per_region = llmin(width_pixels_per_region,
  812.   height_pixels_per_region);
  813. // Round pixels per region to an even number of slider increments
  814. S32 slider_units = llfloor(pixels_per_region / 0.2f);
  815. pixels_per_region = slider_units * 0.2f;
  816. // Make sure the zoom slider can be moved at least a little bit.
  817. // Likewise, less than the increment pixels per region is just silly.
  818. pixels_per_region = llclamp(pixels_per_region, 1.f, ZOOM_MAX);
  819. F32 min_power = log(pixels_per_region/256.f)/log(2.f);
  820. getChild<LLSlider>("zoom slider")->setMinValue(min_power);
  821. }
  822. //-------------------------------------------------------------------------
  823. // User interface widget callbacks
  824. //-------------------------------------------------------------------------
  825. void LLFloaterWorldMap::onGoHome()
  826. {
  827. gAgent.teleportHome();
  828. closeFloater();
  829. }
  830. void LLFloaterWorldMap::onLandmarkComboPrearrange( )
  831. {
  832. if( mIsClosing )
  833. {
  834. return;
  835. }
  836. LLCtrlListInterface *list = childGetListInterface("landmark combo");
  837. if (!list) return;
  838. LLUUID current_choice = list->getCurrentID();
  839. buildLandmarkIDLists();
  840. if( current_choice.isNull() || !list->setCurrentByID( current_choice ) )
  841. {
  842. LLTracker::stopTracking(NULL);
  843. }
  844. }
  845. void LLFloaterWorldMap::onComboTextEntry()
  846. {
  847. // Reset the tracking whenever we start typing into any of the search fields,
  848. // so that hitting <enter> does an auto-complete versus teleporting us to the
  849. // previously selected landmark/friend.
  850. LLTracker::clearFocus();
  851. }
  852. void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl )
  853. {
  854. onComboTextEntry();
  855. updateSearchEnabled();
  856. }
  857. void LLFloaterWorldMap::onLandmarkComboCommit()
  858. {
  859. if( mIsClosing )
  860. {
  861. return;
  862. }
  863. LLCtrlListInterface *list = childGetListInterface("landmark combo");
  864. if (!list) return;
  865. LLUUID asset_id;
  866. LLUUID item_id = list->getCurrentID();
  867. LLTracker::stopTracking(NULL);
  868. //RN: stopTracking() clears current combobox selection, need to reassert it here
  869. list->setCurrentByID(item_id);
  870. if( item_id.isNull() )
  871. {
  872. }
  873. else if( item_id == sHomeID )
  874. {
  875. asset_id = sHomeID;
  876. }
  877. else
  878. {
  879. LLInventoryItem* item = gInventory.getItem( item_id );
  880. if( item )
  881. {
  882. asset_id = item->getAssetUUID();
  883. }
  884. else
  885. {
  886. // Something went wrong, so revert to a safe value.
  887. item_id.setNull();
  888. }
  889. }
  890. trackLandmark( item_id);
  891. onShowTargetBtn();
  892. // Reset to user postion if nothing is tracked
  893. mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
  894. }
  895. // static 
  896. void LLFloaterWorldMap::onAvatarComboPrearrange( )
  897. {
  898. if( mIsClosing )
  899. {
  900. return;
  901. }
  902. LLCtrlListInterface *list = childGetListInterface("friend combo");
  903. if (!list) return;
  904. LLUUID current_choice;
  905. if( LLAvatarTracker::instance().haveTrackingInfo() )
  906. {
  907. current_choice = LLAvatarTracker::instance().getAvatarID();
  908. }
  909. buildAvatarIDList();
  910. if( !list->setCurrentByID( current_choice ) || current_choice.isNull() )
  911. {
  912. LLTracker::stopTracking(NULL);
  913. }
  914. }
  915. void LLFloaterWorldMap::onAvatarComboCommit()
  916. {
  917. if( mIsClosing )
  918. {
  919. return;
  920. }
  921. LLCtrlListInterface *list = childGetListInterface("friend combo");
  922. if (!list) return;
  923. const LLUUID& new_avatar_id = list->getCurrentID();
  924. if (new_avatar_id.notNull())
  925. {
  926. std::string name;
  927. LLComboBox* combo = getChild<LLComboBox>("friend combo");
  928. if (combo) name = combo->getSimple();
  929. trackAvatar(new_avatar_id, name);
  930. onShowTargetBtn();
  931. }
  932. else
  933. { // Reset to user postion if nothing is tracked
  934. mSetToUserPosition = ( LLTracker::getTrackingStatus() == LLTracker::TRACKING_NOTHING );
  935. }
  936. }
  937. void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus )
  938. {
  939. updateSearchEnabled();
  940. }
  941. void LLFloaterWorldMap::updateSearchEnabled()
  942. {
  943. if (childHasKeyboardFocus("location") && 
  944. childGetValue("location").asString().length() > 0)
  945. {
  946. setDefaultBtn("DoSearch");
  947. }
  948. else
  949. {
  950. setDefaultBtn(NULL);
  951. }
  952. }
  953. void LLFloaterWorldMap::onLocationCommit()
  954. {
  955. if( mIsClosing )
  956. {
  957. return;
  958. }
  959. clearLocationSelection(FALSE);
  960. mCompletingRegionName = "";
  961. mLastRegionName = "";
  962. std::string str = childGetValue("location").asString();
  963. // Trim any leading and trailing spaces in the search target
  964. std::string saved_str = str;
  965. LLStringUtil::trim( str );
  966. if ( str != saved_str )
  967. { // Set the value in the UI if any spaces were removed
  968. childSetValue("location", str);
  969. }
  970. LLStringUtil::toLower(str);
  971. mCompletingRegionName = str;
  972. LLWorldMap::getInstance()->setTrackingCommit();
  973. if (str.length() >= 3)
  974. {
  975. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
  976. }
  977. else
  978. {
  979. str += "#";
  980. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(str);
  981. }
  982. }
  983. void LLFloaterWorldMap::onClearBtn()
  984. {
  985. mTrackedStatus = LLTracker::TRACKING_NOTHING;
  986. LLTracker::stopTracking((void *)(intptr_t)TRUE);
  987. LLWorldMap::getInstance()->cancelTracking();
  988. mSLURL = ""; // Clear the SLURL since it's invalid
  989. mSetToUserPosition = TRUE; // Revert back to the current user position
  990. }
  991. void LLFloaterWorldMap::onShowTargetBtn()
  992. {
  993. centerOnTarget(TRUE);
  994. }
  995. void LLFloaterWorldMap::onShowAgentBtn()
  996. {
  997. LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate
  998. // Set flag so user's location will be displayed if not tracking anything else
  999. mSetToUserPosition = TRUE;
  1000. }
  1001. void LLFloaterWorldMap::onClickTeleportBtn()
  1002. {
  1003. teleport();
  1004. }
  1005. void LLFloaterWorldMap::onCopySLURL()
  1006. {
  1007. getWindow()->copyTextToClipboard(utf8str_to_wstring(mSLURL));
  1008. LLSD args;
  1009. args["SLURL"] = mSLURL;
  1010. LLNotificationsUtil::add("CopySLURL", args);
  1011. }
  1012. // protected
  1013. void LLFloaterWorldMap::centerOnTarget(BOOL animate)
  1014. {
  1015. LLVector3d pos_global;
  1016. if(LLTracker::getTrackingStatus() != LLTracker::TRACKING_NOTHING)
  1017. {
  1018. LLVector3d tracked_position = LLTracker::getTrackedPositionGlobal();
  1019. //RN: tracker doesn't allow us to query completion, so we check for a tracking position of
  1020. // absolute zero, and keep trying in the draw loop
  1021. if (tracked_position.isExactlyZero())
  1022. {
  1023. mWaitingForTracker = TRUE;
  1024. return;
  1025. }
  1026. else
  1027. {
  1028. // We've got the position finally, so we're no longer busy. JC
  1029. // getWindow()->decBusyCount();
  1030. pos_global = LLTracker::getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();
  1031. }
  1032. }
  1033. else if(LLWorldMap::getInstance()->isTracking())
  1034. {
  1035. pos_global = LLWorldMap::getInstance()->getTrackedPositionGlobal() - gAgent.getCameraPositionGlobal();;
  1036. }
  1037. else
  1038. {
  1039. // default behavior = center on agent
  1040. pos_global.clearVec();
  1041. }
  1042. LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), 
  1043. -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)),
  1044. !animate);
  1045. mWaitingForTracker = FALSE;
  1046. }
  1047. // protected
  1048. void LLFloaterWorldMap::fly()
  1049. {
  1050. LLVector3d pos_global = LLTracker::getTrackedPositionGlobal();
  1051. // Start the autopilot and close the floater, 
  1052. // so we can see where we're flying
  1053. if (!pos_global.isExactlyZero())
  1054. {
  1055. gAgent.startAutoPilotGlobal( pos_global );
  1056. closeFloater();
  1057. }
  1058. else
  1059. {
  1060. make_ui_sound("UISndInvalidOp");
  1061. }
  1062. }
  1063. // protected
  1064. void LLFloaterWorldMap::teleport()
  1065. {
  1066. BOOL teleport_home = FALSE;
  1067. LLVector3d pos_global;
  1068. LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
  1069. LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
  1070. if (LLTracker::TRACKING_AVATAR == tracking_status
  1071. && av_tracker.haveTrackingInfo() )
  1072. {
  1073. pos_global = av_tracker.getGlobalPos();
  1074. pos_global.mdV[VZ] = childGetValue("spin z");
  1075. }
  1076. else if ( LLTracker::TRACKING_LANDMARK == tracking_status)
  1077. {
  1078. if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
  1079. {
  1080. teleport_home = TRUE;
  1081. }
  1082. else
  1083. {
  1084. LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
  1085. LLUUID region_id;
  1086. if(landmark
  1087.    && !landmark->getGlobalPos(pos_global)
  1088.    && landmark->getRegionID(region_id))
  1089. {
  1090. LLLandmark::requestRegionHandle(
  1091. gMessageSystem,
  1092. gAgent.getRegionHost(),
  1093. region_id,
  1094. NULL);
  1095. }
  1096. }
  1097. }
  1098. else if ( LLTracker::TRACKING_LOCATION == tracking_status)
  1099. {
  1100. pos_global = LLTracker::getTrackedPositionGlobal();
  1101. }
  1102. else
  1103. {
  1104. make_ui_sound("UISndInvalidOp");
  1105. }
  1106. // Do the teleport, which will also close the floater
  1107. if (teleport_home)
  1108. {
  1109. gAgent.teleportHome();
  1110. }
  1111. else if (!pos_global.isExactlyZero())
  1112. {
  1113. if(LLTracker::TRACKING_LANDMARK == tracking_status)
  1114. {
  1115. gAgent.teleportViaLandmark(LLTracker::getTrackedLandmarkAssetID());
  1116. }
  1117. else
  1118. {
  1119. gAgent.teleportViaLocation( pos_global );
  1120. }
  1121. }
  1122. }
  1123. void LLFloaterWorldMap::flyToLandmark()
  1124. {
  1125. LLVector3d destination_pos_global;
  1126. if( !LLTracker::getTrackedLandmarkAssetID().isNull() )
  1127. {
  1128. if (LLTracker::hasLandmarkPosition())
  1129. {
  1130. gAgent.startAutoPilotGlobal( LLTracker::getTrackedPositionGlobal() );
  1131. }
  1132. }
  1133. }
  1134. void LLFloaterWorldMap::teleportToLandmark()
  1135. {
  1136. BOOL has_destination = FALSE;
  1137. LLUUID destination_id; // Null means "home"
  1138. if( LLTracker::getTrackedLandmarkAssetID() == sHomeID )
  1139. {
  1140. has_destination = TRUE;
  1141. }
  1142. else
  1143. {
  1144. LLLandmark* landmark = gLandmarkList.getAsset( LLTracker::getTrackedLandmarkAssetID() );
  1145. LLVector3d global_pos;
  1146. if(landmark && landmark->getGlobalPos(global_pos))
  1147. {
  1148. destination_id = LLTracker::getTrackedLandmarkAssetID();
  1149. has_destination = TRUE;
  1150. }
  1151. else if(landmark)
  1152. {
  1153. // pop up an anonymous request request.
  1154. LLUUID region_id;
  1155. if(landmark->getRegionID(region_id))
  1156. {
  1157. LLLandmark::requestRegionHandle(
  1158. gMessageSystem,
  1159. gAgent.getRegionHost(),
  1160. region_id,
  1161. NULL);
  1162. }
  1163. }
  1164. }
  1165. if( has_destination )
  1166. {
  1167. gAgent.teleportViaLandmark( destination_id );
  1168. }
  1169. }
  1170. void LLFloaterWorldMap::teleportToAvatar()
  1171. {
  1172. LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
  1173. if(av_tracker.haveTrackingInfo())
  1174. {
  1175. LLVector3d pos_global = av_tracker.getGlobalPos();
  1176. gAgent.teleportViaLocation( pos_global );
  1177. }
  1178. }
  1179. void LLFloaterWorldMap::flyToAvatar()
  1180. {
  1181. if( LLAvatarTracker::instance().haveTrackingInfo() )
  1182. {
  1183. gAgent.startAutoPilotGlobal( LLAvatarTracker::instance().getGlobalPos() );
  1184. }
  1185. }
  1186. void LLFloaterWorldMap::updateSims(bool found_null_sim)
  1187. {
  1188. if (mCompletingRegionName == "")
  1189. {
  1190. return;
  1191. }
  1192. LLScrollListCtrl *list = getChild<LLScrollListCtrl>("search_results");
  1193. list->operateOnAll(LLCtrlListInterface::OP_DELETE);
  1194. S32 name_length = mCompletingRegionName.length();
  1195. LLSD match;
  1196. S32 num_results = 0;
  1197. std::map<U64, LLSimInfo*>::const_iterator it;
  1198. for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it)
  1199. {
  1200. LLSimInfo* info = it->second;
  1201. std::string sim_name_lower = info->getName();
  1202. LLStringUtil::toLower(sim_name_lower);
  1203. if (sim_name_lower.substr(0, name_length) == mCompletingRegionName)
  1204. {
  1205. if (sim_name_lower == mCompletingRegionName)
  1206. {
  1207. match = info->getName();
  1208. }
  1209. LLSD value;
  1210. value["id"] = info->getName();
  1211. value["columns"][0]["column"] = "sim_name";
  1212. value["columns"][0]["value"] = info->getName();
  1213. list->addElement(value);
  1214. num_results++;
  1215. }
  1216. }
  1217. if (found_null_sim)
  1218. {
  1219. mCompletingRegionName = "";
  1220. }
  1221. // if match found, highlight it and go
  1222. if (!match.isUndefined())
  1223. {
  1224. list->selectByValue(match);
  1225. childSetFocus("search_results");
  1226. onCommitSearchResult();
  1227. }
  1228. // if we found nothing, say "none"
  1229. if (num_results == 0)
  1230. {
  1231. list->setCommentText(LLTrans::getString("worldmap_results_none_found"));
  1232. list->operateOnAll(LLCtrlListInterface::OP_DESELECT);
  1233. }
  1234. }
  1235. void LLFloaterWorldMap::onCommitSearchResult()
  1236. {
  1237. LLCtrlListInterface *list = childGetListInterface("search_results");
  1238. if (!list) return;
  1239. LLSD selected_value = list->getSelectedValue();
  1240. std::string sim_name = selected_value.asString();
  1241. if (sim_name.empty())
  1242. {
  1243. return;
  1244. }
  1245. LLStringUtil::toLower(sim_name);
  1246. std::map<U64, LLSimInfo*>::const_iterator it;
  1247. for (it = LLWorldMap::getInstance()->getRegionMap().begin(); it != LLWorldMap::getInstance()->getRegionMap().end(); ++it)
  1248. {
  1249. LLSimInfo* info = it->second;
  1250. if (info->isName(sim_name))
  1251. {
  1252. LLVector3d pos_global = info->getGlobalOrigin();
  1253. const F64 SIM_COORD_DEFAULT = 128.0;
  1254. LLVector3 pos_local(SIM_COORD_DEFAULT, SIM_COORD_DEFAULT, 0.0f);
  1255. // Did this value come from a trackURL() request?
  1256. if (!mCompletingRegionPos.isExactlyZero())
  1257. {
  1258. pos_local = mCompletingRegionPos;
  1259. mCompletingRegionPos.clear();
  1260. }
  1261. pos_global.mdV[VX] += (F64)pos_local.mV[VX];
  1262. pos_global.mdV[VY] += (F64)pos_local.mV[VY];
  1263. pos_global.mdV[VZ] = (F64)pos_local.mV[VZ];
  1264. childSetValue("location", sim_name);
  1265. trackLocation(pos_global);
  1266. setDefaultBtn("Teleport");
  1267. break;
  1268. }
  1269. }
  1270. onShowTargetBtn();
  1271. }