00001
00032 #include "llviewerprecompiledheaders.h"
00033
00034 #include "llviewerparcelmgr.h"
00035
00036
00037 #include "audioengine.h"
00038 #include "indra_constants.h"
00039 #include "llcachename.h"
00040 #include "llgl.h"
00041 #include "llparcel.h"
00042 #include "llsecondlifeurls.h"
00043 #include "message.h"
00044
00045
00046 #include "llagent.h"
00047 #include "llfloatergroupinfo.h"
00048 #include "llviewerwindow.h"
00049 #include "llviewercontrol.h"
00050 #include "llfirstuse.h"
00051 #include "llfloaterbuyland.h"
00052 #include "llfloatergroups.h"
00053
00054 #include "llfloatersellland.h"
00055 #include "llfloatertools.h"
00056 #include "llnotify.h"
00057 #include "llparcelselection.h"
00058 #include "llresmgr.h"
00059 #include "llsdutil.h"
00060 #include "llstatusbar.h"
00061 #include "llui.h"
00062 #include "llviewerimage.h"
00063 #include "llviewerimagelist.h"
00064 #include "llviewermenu.h"
00065 #include "llviewerparcelmedia.h"
00066 #include "llviewerparceloverlay.h"
00067 #include "llviewerregion.h"
00068 #include "llworld.h"
00069 #include "lloverlaybar.h"
00070 #include "roles_constants.h"
00071 #include "llweb.h"
00072
00073 const F32 PARCEL_COLLISION_DRAW_SECS = 1.f;
00074
00075
00076
00077
00078 U8* LLViewerParcelMgr::sPackedOverlay = NULL;
00079
00080 LLUUID gCurrentMovieID = LLUUID::null;
00081
00082 LLPointer<LLViewerImage> sBlockedImage;
00083 LLPointer<LLViewerImage> sPassImage;
00084
00085
00086 void optionally_start_music(const LLString& music_url);
00087 void callback_start_music(S32 option, void* data);
00088 void optionally_prepare_video(const LLParcel *parcelp);
00089 void callback_prepare_video(S32 option, void* data);
00090 void prepare_video(const LLParcel *parcelp);
00091 void start_video(const LLParcel *parcelp);
00092 void stop_video();
00093 void callback_god_force_owner(S32 option, void* user_data);
00094
00095 struct LLGodForceOwnerData
00096 {
00097 LLUUID mOwnerID;
00098 S32 mLocalID;
00099 LLHost mHost;
00100
00101 LLGodForceOwnerData(
00102 const LLUUID& owner_id,
00103 S32 local_parcel_id,
00104 const LLHost& host) :
00105 mOwnerID(owner_id),
00106 mLocalID(local_parcel_id),
00107 mHost(host) {}
00108 };
00109
00110
00111
00112
00113 LLViewerParcelMgr::LLViewerParcelMgr()
00114 : mSelected(FALSE),
00115 mWestSouth(),
00116 mEastNorth(),
00117 mSelectedDwell(0.f),
00118 mAgentParcelSequenceID(-1),
00119 mHoverWestSouth(),
00120 mHoverEastNorth(),
00121 mRenderCollision(FALSE),
00122 mRenderSelection(TRUE),
00123 mCollisionBanned(0),
00124 mCollisionTimer()
00125 {
00126 mCurrentParcel = new LLParcel();
00127 mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00128 mFloatingParcelSelection = new LLParcelSelection(mCurrentParcel);
00129
00130 mAgentParcel = new LLParcel();
00131 mHoverParcel = new LLParcel();
00132 mCollisionParcel = new LLParcel();
00133
00134 mParcelsPerEdge = S32( REGION_WIDTH_METERS / PARCEL_GRID_STEP_METERS );
00135 mHighlightSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
00136 resetSegments(mHighlightSegments);
00137
00138 mCollisionSegments = new U8[(mParcelsPerEdge+1)*(mParcelsPerEdge+1)];
00139 resetSegments(mCollisionSegments);
00140
00141 mBlockedImage = gImageList.getImageFromFile("noentrylines.j2c");
00142 mPassImage = gImageList.getImageFromFile("noentrypasslines.j2c");
00143
00144 S32 overlay_size = mParcelsPerEdge * mParcelsPerEdge / PARCEL_OVERLAY_CHUNKS;
00145 sPackedOverlay = new U8[overlay_size];
00146
00147 mAgentParcelOverlay = new U8[mParcelsPerEdge * mParcelsPerEdge];
00148 S32 i;
00149 for (i = 0; i < mParcelsPerEdge * mParcelsPerEdge; i++)
00150 {
00151 mAgentParcelOverlay[i] = 0;
00152 }
00153 }
00154
00155
00156 LLViewerParcelMgr::~LLViewerParcelMgr()
00157 {
00158 mCurrentParcelSelection->setParcel(NULL);
00159 mCurrentParcelSelection = NULL;
00160
00161 mFloatingParcelSelection->setParcel(NULL);
00162 mFloatingParcelSelection = NULL;
00163
00164 delete mCurrentParcel;
00165 mCurrentParcel = NULL;
00166
00167 delete mAgentParcel;
00168 mAgentParcel = NULL;
00169
00170 delete mCollisionParcel;
00171 mCollisionParcel = NULL;
00172
00173 delete mHoverParcel;
00174 mHoverParcel = NULL;
00175
00176 delete[] mHighlightSegments;
00177 mHighlightSegments = NULL;
00178
00179 delete[] mCollisionSegments;
00180 mCollisionSegments = NULL;
00181
00182 delete[] sPackedOverlay;
00183 sPackedOverlay = NULL;
00184
00185 delete[] mAgentParcelOverlay;
00186 mAgentParcelOverlay = NULL;
00187
00188 sBlockedImage = NULL;
00189 sPassImage = NULL;
00190 }
00191
00192 void LLViewerParcelMgr::dump()
00193 {
00194 llinfos << "Parcel Manager Dump" << llendl;
00195 llinfos << "mSelected " << S32(mSelected) << llendl;
00196 llinfos << "Selected parcel: " << llendl;
00197 llinfos << mWestSouth << " to " << mEastNorth << llendl;
00198 mCurrentParcel->dump();
00199 llinfos << "banning " << mCurrentParcel->mBanList.size() << llendl;
00200
00201 access_map_const_iterator cit = mCurrentParcel->mBanList.begin();
00202 access_map_const_iterator end = mCurrentParcel->mBanList.end();
00203 for ( ; cit != end; ++cit)
00204 {
00205 llinfos << "ban id " << (*cit).first << llendl;
00206 }
00207 llinfos << "Hover parcel:" << llendl;
00208 mHoverParcel->dump();
00209 llinfos << "Agent parcel:" << llendl;
00210 mAgentParcel->dump();
00211 }
00212
00213
00214 LLViewerRegion* LLViewerParcelMgr::getSelectionRegion()
00215 {
00216 return LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00217 }
00218
00219
00220 void LLViewerParcelMgr::getDisplayInfo(S32* area_out, S32* claim_out,
00221 S32* rent_out,
00222 BOOL* for_sale_out,
00223 F32* dwell_out)
00224 {
00225 S32 area = 0;
00226 S32 price = 0;
00227 S32 rent = 0;
00228 BOOL for_sale = FALSE;
00229 F32 dwell = 0.f;
00230
00231 if (mSelected)
00232 {
00233 if (mCurrentParcelSelection->mSelectedMultipleOwners)
00234 {
00235 area = mCurrentParcelSelection->getClaimableArea();
00236 }
00237 else
00238 {
00239 area = getSelectedArea();
00240 }
00241
00242 if (mCurrentParcel->getForSale())
00243 {
00244 price = mCurrentParcel->getSalePrice();
00245 for_sale = TRUE;
00246 }
00247 else
00248 {
00249 price = area * mCurrentParcel->getClaimPricePerMeter();
00250 for_sale = FALSE;
00251 }
00252
00253 rent = mCurrentParcel->getTotalRent();
00254
00255 dwell = mSelectedDwell;
00256 }
00257
00258 *area_out = area;
00259 *claim_out = price;
00260 *rent_out = rent;
00261 *for_sale_out = for_sale;
00262 *dwell_out = dwell;
00263 }
00264
00265 S32 LLViewerParcelMgr::getSelectedArea() const
00266 {
00267 S32 rv = 0;
00268 if(mSelected && mCurrentParcel && mCurrentParcelSelection->mWholeParcelSelected)
00269 {
00270 rv = mCurrentParcel->getArea();
00271 }
00272 else if(mSelected)
00273 {
00274 F64 width = mEastNorth.mdV[VX] - mWestSouth.mdV[VX];
00275 F64 height = mEastNorth.mdV[VY] - mWestSouth.mdV[VY];
00276 F32 area = (F32)(width * height);
00277 rv = llround(area);
00278 }
00279 return rv;
00280 }
00281
00282 void LLViewerParcelMgr::resetSegments(U8* segments)
00283 {
00284 S32 i;
00285 S32 count = (mParcelsPerEdge+1)*(mParcelsPerEdge+1);
00286 for (i = 0; i < count; i++)
00287 {
00288 segments[i] = 0x0;
00289 }
00290 }
00291
00292
00293 void LLViewerParcelMgr::writeHighlightSegments(F32 west, F32 south, F32 east,
00294 F32 north)
00295 {
00296 S32 x, y;
00297 S32 min_x = llround( west / PARCEL_GRID_STEP_METERS );
00298 S32 max_x = llround( east / PARCEL_GRID_STEP_METERS );
00299 S32 min_y = llround( south / PARCEL_GRID_STEP_METERS );
00300 S32 max_y = llround( north / PARCEL_GRID_STEP_METERS );
00301
00302 const S32 STRIDE = mParcelsPerEdge+1;
00303
00304
00305 y = min_y;
00306 for (x = min_x; x < max_x; x++)
00307 {
00308
00309
00310 mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
00311 }
00312
00313
00314 x = min_x;
00315 for (y = min_y; y < max_y; y++)
00316 {
00317 mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
00318 }
00319
00320
00321
00322 y = max_y;
00323 for (x = min_x; x < max_x; x++)
00324 {
00325 mHighlightSegments[x + y*STRIDE] ^= SOUTH_MASK;
00326 }
00327
00328
00329 x = max_x;
00330 for (y = min_y; y < max_y; y++)
00331 {
00332 mHighlightSegments[x + y*STRIDE] ^= WEST_MASK;
00333 }
00334 }
00335
00336
00337 void LLViewerParcelMgr::writeSegmentsFromBitmap(U8* bitmap, U8* segments)
00338 {
00339 S32 x;
00340 S32 y;
00341 const S32 IN_STRIDE = mParcelsPerEdge;
00342 const S32 OUT_STRIDE = mParcelsPerEdge+1;
00343
00344 for (y = 0; y < IN_STRIDE; y++)
00345 {
00346 x = 0;
00347 while( x < IN_STRIDE )
00348 {
00349 U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
00350
00351 S32 bit;
00352 for (bit = 0; bit < 8; bit++)
00353 {
00354 if (byte & (1 << bit) )
00355 {
00356 S32 out = x+y*OUT_STRIDE;
00357
00358
00359 segments[out] ^= SOUTH_MASK;
00360 segments[out+OUT_STRIDE] ^= SOUTH_MASK;
00361
00362
00363 segments[out] ^= WEST_MASK;
00364 segments[out+1] ^= WEST_MASK;
00365 }
00366 x++;
00367 }
00368 }
00369 }
00370 }
00371
00372
00373 void LLViewerParcelMgr::writeAgentParcelFromBitmap(U8* bitmap)
00374 {
00375 S32 x;
00376 S32 y;
00377 const S32 IN_STRIDE = mParcelsPerEdge;
00378
00379 for (y = 0; y < IN_STRIDE; y++)
00380 {
00381 x = 0;
00382 while( x < IN_STRIDE )
00383 {
00384 U8 byte = bitmap[ (x + y*IN_STRIDE) / 8 ];
00385
00386 S32 bit;
00387 for (bit = 0; bit < 8; bit++)
00388 {
00389 if (byte & (1 << bit) )
00390 {
00391 mAgentParcelOverlay[x+y*IN_STRIDE] = 1;
00392 }
00393 else
00394 {
00395 mAgentParcelOverlay[x+y*IN_STRIDE] = 0;
00396 }
00397 x++;
00398 }
00399 }
00400 }
00401 }
00402
00403
00404
00405
00406 LLParcelSelectionHandle LLViewerParcelMgr::selectParcelAt(const LLVector3d& pos_global)
00407 {
00408 LLVector3d southwest = pos_global;
00409 LLVector3d northeast = pos_global;
00410
00411 southwest -= LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
00412 southwest.mdV[VX] = llround( southwest.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
00413 southwest.mdV[VY] = llround( southwest.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
00414
00415 northeast += LLVector3d( PARCEL_GRID_STEP_METERS/2, PARCEL_GRID_STEP_METERS/2, 0 );
00416 northeast.mdV[VX] = llround( northeast.mdV[VX], (F64)PARCEL_GRID_STEP_METERS );
00417 northeast.mdV[VY] = llround( northeast.mdV[VY], (F64)PARCEL_GRID_STEP_METERS );
00418
00419
00420 return selectLand( southwest, northeast, TRUE );
00421 }
00422
00423
00424
00425 LLParcelSelectionHandle LLViewerParcelMgr::selectParcelInRectangle()
00426 {
00427 return selectLand(mWestSouth, mEastNorth, TRUE);
00428 }
00429
00430
00431 void LLViewerParcelMgr::selectCollisionParcel()
00432 {
00433
00434 mWestSouth = gAgent.getRegion()->getOriginGlobal();
00435 mEastNorth = mWestSouth;
00436 mEastNorth += LLVector3d(PARCEL_GRID_STEP_METERS, PARCEL_GRID_STEP_METERS, 0.0);
00437
00438
00439 LLMessageSystem *msg = gMessageSystem;
00440 msg->newMessageFast(_PREHASH_ParcelPropertiesRequestByID);
00441 msg->nextBlockFast(_PREHASH_AgentID);
00442 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00443 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00444 msg->nextBlockFast(_PREHASH_ParcelData);
00445 msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
00446 msg->addS32Fast(_PREHASH_LocalID, mCollisionParcel->getLocalID() );
00447 gAgent.sendReliableMessage();
00448
00449 mRequestResult = PARCEL_RESULT_NO_DATA;
00450
00451
00452 mCurrentParcel->setName( mCollisionParcel->getName() );
00453 mCurrentParcel->setDesc( mCollisionParcel->getDesc() );
00454 mCurrentParcel->setPassPrice(mCollisionParcel->getPassPrice());
00455 mCurrentParcel->setPassHours(mCollisionParcel->getPassHours());
00456
00457
00458 resetSegments(mHighlightSegments);
00459
00460 mFloatingParcelSelection->setParcel(mCurrentParcel);
00461 mCurrentParcelSelection->setParcel(NULL);
00462 mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00463
00464 mSelected = TRUE;
00465 mCurrentParcelSelection->mWholeParcelSelected = TRUE;
00466 notifyObservers();
00467 return;
00468 }
00469
00470
00471
00472 LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1, const LLVector3d &corner2,
00473 BOOL snap_selection)
00474 {
00475 sanitize_corners( corner1, corner2, mWestSouth, mEastNorth );
00476
00477
00478 F32 delta_x = getSelectionWidth();
00479 if (delta_x * delta_x <= 1.f * 1.f)
00480 {
00481 mSelected = FALSE;
00482 notifyObservers();
00483 return NULL;
00484 }
00485
00486
00487 F32 delta_y = getSelectionHeight();
00488 if (delta_y * delta_y <= 1.f * 1.f)
00489 {
00490 mSelected = FALSE;
00491 notifyObservers();
00492 return NULL;
00493 }
00494
00495
00496
00497
00498 LLVector3d east_north_region_check( mEastNorth );
00499 east_north_region_check.mdV[VX] -= 0.5;
00500 east_north_region_check.mdV[VY] -= 0.5;
00501
00502 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth);
00503 LLViewerRegion *region_other = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
00504
00505 if(!region)
00506 {
00507
00508 mSelected = FALSE;
00509 return NULL;
00510 }
00511
00512 if (region != region_other)
00513 {
00514 LLNotifyBox::showXml("CantSelectLandFromMultipleRegions");
00515 mSelected = FALSE;
00516 notifyObservers();
00517 return NULL;
00518 }
00519
00520
00521 LLVector3 wsb_region = region->getPosRegionFromGlobal( mWestSouth );
00522 LLVector3 ent_region = region->getPosRegionFromGlobal( mEastNorth );
00523
00524
00525 LLMessageSystem *msg = gMessageSystem;
00526 msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
00527 msg->nextBlockFast(_PREHASH_AgentData);
00528 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
00529 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
00530 msg->nextBlockFast(_PREHASH_ParcelData);
00531 msg->addS32Fast(_PREHASH_SequenceID, SELECTED_PARCEL_SEQ_ID );
00532 msg->addF32Fast(_PREHASH_West, wsb_region.mV[VX] );
00533 msg->addF32Fast(_PREHASH_South, wsb_region.mV[VY] );
00534 msg->addF32Fast(_PREHASH_East, ent_region.mV[VX] );
00535 msg->addF32Fast(_PREHASH_North, ent_region.mV[VY] );
00536 msg->addBOOL("SnapSelection", snap_selection);
00537 msg->sendReliable( region->getHost() );
00538
00539 mRequestResult = PARCEL_RESULT_NO_DATA;
00540
00541
00542 resetSegments(mHighlightSegments);
00543
00544 mFloatingParcelSelection->setParcel(mCurrentParcel);
00545 mCurrentParcelSelection->setParcel(NULL);
00546 mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00547
00548 mSelected = TRUE;
00549 mCurrentParcelSelection->mWholeParcelSelected = snap_selection;
00550 notifyObservers();
00551 return mCurrentParcelSelection;
00552 }
00553
00554 void LLViewerParcelMgr::deselectUnused()
00555 {
00556
00557 if (mCurrentParcelSelection->getNumRefs() == 1 && mFloatingParcelSelection->getNumRefs() == 1)
00558 {
00559 deselectLand();
00560 }
00561 }
00562
00563 void LLViewerParcelMgr::deselectLand()
00564 {
00565 if (mSelected)
00566 {
00567 mSelected = FALSE;
00568
00569
00570 mCurrentParcel->setLocalID(-1);
00571 mCurrentParcel->mAccessList.clear();
00572 mCurrentParcel->mBanList.clear();
00573
00574
00575 mSelectedDwell = 0.f;
00576
00577
00578 mCurrentParcelSelection->setParcel(NULL);
00579 mFloatingParcelSelection->setParcel(NULL);
00580
00581 mCurrentParcelSelection = new LLParcelSelection(mCurrentParcel);
00582
00583 notifyObservers();
00584 }
00585 }
00586
00587
00588 void LLViewerParcelMgr::addObserver(LLParcelObserver* observer)
00589 {
00590 mObservers.put(observer);
00591 }
00592
00593
00594 void LLViewerParcelMgr::removeObserver(LLParcelObserver* observer)
00595 {
00596 mObservers.removeObj(observer);
00597 }
00598
00599
00600
00601
00602
00603 void LLViewerParcelMgr::notifyObservers()
00604 {
00605 LLDynamicArray<LLParcelObserver*> observers;
00606 S32 count = mObservers.count();
00607 S32 i;
00608 for(i = 0; i < count; ++i)
00609 {
00610 observers.put(mObservers.get(i));
00611 }
00612 for(i = 0; i < count; ++i)
00613 {
00614 observers.get(i)->changed();
00615 }
00616 }
00617
00618
00619
00620
00621
00622 BOOL LLViewerParcelMgr::selectionEmpty() const
00623 {
00624 return !mSelected;
00625 }
00626
00627
00628 LLParcelSelectionHandle LLViewerParcelMgr::getParcelSelection() const
00629 {
00630 return mCurrentParcelSelection;
00631 }
00632
00633 LLParcelSelectionHandle LLViewerParcelMgr::getFloatingParcelSelection() const
00634 {
00635 return mFloatingParcelSelection;
00636 }
00637
00638 LLParcel *LLViewerParcelMgr::getAgentParcel() const
00639 {
00640 return mAgentParcel;
00641 }
00642
00643
00644 BOOL LLViewerParcelMgr::agentCanBuild() const
00645 {
00646 if (mAgentParcel)
00647 {
00648 return (gAgent.isGodlike()
00649 || (mAgentParcel->allowModifyBy(
00650 gAgent.getID(),
00651 gAgent.getGroupID())));
00652 }
00653 else
00654 {
00655 return gAgent.isGodlike();
00656 }
00657 }
00658
00659 BOOL LLViewerParcelMgr::agentCanTakeDamage() const
00660 {
00661 return mAgentParcel->getAllowDamage();
00662 }
00663
00664 BOOL LLViewerParcelMgr::agentCanFly() const
00665 {
00666 return TRUE;
00667 }
00668
00669 F32 LLViewerParcelMgr::agentDrawDistance() const
00670 {
00671 return 512.f;
00672 }
00673
00674 BOOL LLViewerParcelMgr::isOwnedAt(const LLVector3d& pos_global) const
00675 {
00676 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
00677 if (!region) return FALSE;
00678
00679 LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00680 if (!overlay) return FALSE;
00681
00682 LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00683
00684 return overlay->isOwned( pos_region );
00685 }
00686
00687 BOOL LLViewerParcelMgr::isOwnedSelfAt(const LLVector3d& pos_global) const
00688 {
00689 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
00690 if (!region) return FALSE;
00691
00692 LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00693 if (!overlay) return FALSE;
00694
00695 LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00696
00697 return overlay->isOwnedSelf( pos_region );
00698 }
00699
00700 BOOL LLViewerParcelMgr::isOwnedOtherAt(const LLVector3d& pos_global) const
00701 {
00702 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
00703 if (!region) return FALSE;
00704
00705 LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00706 if (!overlay) return FALSE;
00707
00708 LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00709
00710 return overlay->isOwnedOther( pos_region );
00711 }
00712
00713 BOOL LLViewerParcelMgr::isSoundLocal(const LLVector3d& pos_global) const
00714 {
00715 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos_global );
00716 if (!region) return FALSE;
00717
00718 LLViewerParcelOverlay* overlay = region->getParcelOverlay();
00719 if (!overlay) return FALSE;
00720
00721 LLVector3 pos_region = region->getPosRegionFromGlobal( pos_global );
00722
00723 return overlay->isSoundLocal( pos_region );
00724 }
00725
00726 BOOL LLViewerParcelMgr::canHearSound(const LLVector3d &pos_global) const
00727 {
00728 BOOL in_agent_parcel = inAgentParcel(pos_global);
00729
00730 if (in_agent_parcel)
00731 {
00732
00733 return TRUE;
00734 }
00735 else
00736 {
00737 if (LLViewerParcelMgr::getInstance()->getAgentParcel()->getSoundLocal())
00738 {
00739
00740 return FALSE;
00741 }
00742 else if (LLViewerParcelMgr::getInstance()->isSoundLocal(pos_global))
00743 {
00744
00745 return FALSE;
00746 }
00747 else
00748 {
00749
00750 return TRUE;
00751 }
00752 }
00753 }
00754
00755
00756 BOOL LLViewerParcelMgr::inAgentParcel(const LLVector3d &pos_global) const
00757 {
00758 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(pos_global);
00759 if (region != gAgent.getRegion())
00760 {
00761
00762 return FALSE;
00763 }
00764
00765 LLVector3 pos_region = gAgent.getRegion()->getPosRegionFromGlobal(pos_global);
00766 S32 row = S32(pos_region.mV[VY] / PARCEL_GRID_STEP_METERS);
00767 S32 column = S32(pos_region.mV[VX] / PARCEL_GRID_STEP_METERS);
00768
00769 if (mAgentParcelOverlay[row*mParcelsPerEdge + column])
00770 {
00771 return TRUE;
00772 }
00773 else
00774 {
00775 return FALSE;
00776 }
00777 }
00778
00779
00780 LLParcel* LLViewerParcelMgr::getHoverParcel() const
00781 {
00782 if (mHoverRequestResult == PARCEL_RESULT_SUCCESS)
00783 {
00784 return mHoverParcel;
00785 }
00786 else
00787 {
00788 return NULL;
00789 }
00790 }
00791
00792
00793 LLParcel* LLViewerParcelMgr::getCollisionParcel() const
00794 {
00795 if (mRenderCollision)
00796 {
00797 return mCollisionParcel;
00798 }
00799 else
00800 {
00801 return NULL;
00802 }
00803 }
00804
00805
00806
00807
00808
00809 void LLViewerParcelMgr::render()
00810 {
00811 if (mSelected && mRenderSelection)
00812 {
00813
00814
00815 LLViewerRegion* regionp = LLWorld::getInstance()->getRegionFromPosGlobal(mWestSouth);
00816 if (!regionp) return;
00817
00818 renderHighlightSegments(mHighlightSegments, regionp);
00819 }
00820 }
00821
00822
00823 void LLViewerParcelMgr::renderParcelCollision()
00824 {
00825
00826 if (mCollisionTimer.getElapsedTimeF32() > PARCEL_COLLISION_DRAW_SECS)
00827 {
00828 mRenderCollision = FALSE;
00829 }
00830
00831 if (mRenderCollision)
00832 {
00833 LLViewerRegion* regionp = gAgent.getRegion();
00834 BOOL use_pass = mCollisionParcel->getParcelFlag(PF_USE_PASS_LIST);
00835 renderCollisionSegments(mCollisionSegments, use_pass, regionp);
00836 }
00837 }
00838
00839
00840 void LLViewerParcelMgr::sendParcelAccessListRequest(U32 flags)
00841 {
00842 if (!mSelected)
00843 {
00844 return;
00845 }
00846
00847 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00848 if (!region) return;
00849
00850 LLMessageSystem *msg = gMessageSystem;
00851
00852
00853 if (flags & AL_BAN)
00854 {
00855 mCurrentParcel->mBanList.clear();
00856 }
00857 if (flags & AL_ACCESS)
00858 {
00859 mCurrentParcel->mAccessList.clear();
00860 }
00861
00862
00863 msg->newMessageFast(_PREHASH_ParcelAccessListRequest);
00864 msg->nextBlockFast(_PREHASH_AgentData);
00865 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00866 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00867 msg->nextBlockFast(_PREHASH_Data);
00868 msg->addS32Fast(_PREHASH_SequenceID, 0);
00869 msg->addU32Fast(_PREHASH_Flags, flags);
00870 msg->addS32("LocalID", mCurrentParcel->getLocalID() );
00871 msg->sendReliable( region->getHost() );
00872 }
00873
00874
00875 void LLViewerParcelMgr::sendParcelDwellRequest()
00876 {
00877 if (!mSelected)
00878 {
00879 return;
00880 }
00881
00882 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00883 if (!region) return;
00884
00885 LLMessageSystem *msg = gMessageSystem;
00886
00887
00888 msg->newMessage("ParcelDwellRequest");
00889 msg->nextBlock("AgentData");
00890 msg->addUUID("AgentID", gAgent.getID() );
00891 msg->addUUID("SessionID", gAgent.getSessionID());
00892 msg->nextBlock("Data");
00893 msg->addS32("LocalID", mCurrentParcel->getLocalID());
00894 msg->addUUID("ParcelID", LLUUID::null);
00895 msg->sendReliable( region->getHost() );
00896 }
00897
00898
00899 void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
00900 {
00901 if (!mSelected)
00902 {
00903 gViewerWindow->alertXml("CannotSetLandOwnerNothingSelected");
00904 return;
00905 }
00906
00907 llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
00908
00909
00910 LLVector3d east_north_region_check( mEastNorth );
00911 east_north_region_check.mdV[VX] -= 0.5;
00912 east_north_region_check.mdV[VY] -= 0.5;
00913
00914 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00915 if (!region)
00916 {
00917
00918 gViewerWindow->alertXml("CannotContentifyNoRegion");
00919 return;
00920 }
00921
00922
00923 LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
00924 if (region != region2)
00925 {
00926 gViewerWindow->alertXml("CannotSetLandOwnerMultipleRegions");
00927 return;
00928 }
00929
00930 llinfos << "Region " << region->getOriginGlobal() << llendl;
00931
00932 LLGodForceOwnerData* data = new LLGodForceOwnerData(owner_id, mCurrentParcel->getLocalID(), region->getHost());
00933 if(mCurrentParcel->getAuctionID())
00934 {
00935 gViewerWindow->alertXml("ForceOwnerAuctionWarning",
00936 callback_god_force_owner,
00937 (void*)data);
00938 }
00939 else
00940 {
00941 callback_god_force_owner(0, (void*)data);
00942 }
00943 }
00944
00945 void callback_god_force_owner(S32 option, void* user_data)
00946 {
00947 LLGodForceOwnerData* data = (LLGodForceOwnerData*)user_data;
00948 if(data && (0 == option))
00949 {
00950 LLMessageSystem* msg = gMessageSystem;
00951 msg->newMessage("ParcelGodForceOwner");
00952 msg->nextBlock("AgentData");
00953 msg->addUUID("AgentID", gAgent.getID());
00954 msg->addUUID("SessionID", gAgent.getSessionID());
00955 msg->nextBlock("Data");
00956 msg->addUUID("OwnerID", data->mOwnerID);
00957 msg->addS32( "LocalID", data->mLocalID);
00958 msg->sendReliable(data->mHost);
00959 }
00960 delete data;
00961 }
00962
00963 void LLViewerParcelMgr::sendParcelGodForceToContent()
00964 {
00965 if (!mSelected)
00966 {
00967 gViewerWindow->alertXml("CannotContentifyNothingSelected");
00968 return;
00969 }
00970 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00971 if (!region)
00972 {
00973 gViewerWindow->alertXml("CannotContentifyNoRegion");
00974 return;
00975 }
00976
00977 LLMessageSystem* msg = gMessageSystem;
00978 msg->newMessage("ParcelGodMarkAsContent");
00979 msg->nextBlock("AgentData");
00980 msg->addUUID("AgentID", gAgent.getID());
00981 msg->addUUID("SessionID", gAgent.getSessionID());
00982 msg->nextBlock("ParcelData");
00983 msg->addS32("LocalID", mCurrentParcel->getLocalID());
00984 msg->sendReliable(region->getHost());
00985 }
00986
00987 void LLViewerParcelMgr::sendParcelRelease()
00988 {
00989 if (!mSelected)
00990 {
00991 gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
00992 return;
00993 }
00994
00995 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
00996 if (!region)
00997 {
00998 gViewerWindow->alertXml("CannotReleaseLandNoRegion");
00999 return;
01000 }
01001
01002
01003
01004
01005 LLMessageSystem* msg = gMessageSystem;
01006 msg->newMessage("ParcelRelease");
01007 msg->nextBlock("AgentData");
01008 msg->addUUID("AgentID", gAgent.getID() );
01009 msg->addUUID("SessionID", gAgent.getSessionID() );
01010 msg->nextBlock("Data");
01011 msg->addS32("LocalID", mCurrentParcel->getLocalID() );
01012
01013 msg->sendReliable( region->getHost() );
01014
01015
01016
01017 deselectLand();
01018 }
01019
01020 class LLViewerParcelMgr::ParcelBuyInfo
01021 {
01022 public:
01023 LLUUID mAgent;
01024 LLUUID mSession;
01025 LLUUID mGroup;
01026 BOOL mIsGroupOwned;
01027 BOOL mRemoveContribution;
01028 BOOL mIsClaim;
01029 LLHost mHost;
01030
01031
01032 S32 mParcelID;
01033 S32 mPrice;
01034 S32 mArea;
01035
01036
01037 F32 mWest;
01038 F32 mSouth;
01039 F32 mEast;
01040 F32 mNorth;
01041 };
01042
01043 LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
01044 const LLUUID& agent_id,
01045 const LLUUID& session_id,
01046 const LLUUID& group_id,
01047 BOOL is_group_owned,
01048 BOOL is_claim,
01049 BOOL remove_contribution)
01050 {
01051 if (!mSelected || !mCurrentParcel)
01052 {
01053 gViewerWindow->alertXml("CannotBuyLandNothingSelected");
01054 return NULL;
01055 }
01056
01057 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
01058 if (!region)
01059 {
01060 gViewerWindow->alertXml("CannotBuyLandNoRegion");
01061 return NULL;
01062 }
01063
01064 if (is_claim)
01065 {
01066 llinfos << "Claiming " << mWestSouth << " to " << mEastNorth << llendl;
01067 llinfos << "Region " << region->getOriginGlobal() << llendl;
01068
01069
01070 LLVector3d east_north_region_check( mEastNorth );
01071 east_north_region_check.mdV[VX] -= 0.5;
01072 east_north_region_check.mdV[VY] -= 0.5;
01073
01074 LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
01075
01076 if (region != region2)
01077 {
01078 gViewerWindow->alertXml("CantBuyLandAcrossMultipleRegions");
01079 return NULL;
01080 }
01081 }
01082
01083
01084 ParcelBuyInfo* info = new ParcelBuyInfo;
01085
01086 info->mAgent = agent_id;
01087 info->mSession = session_id;
01088 info->mGroup = group_id;
01089 info->mIsGroupOwned = is_group_owned;
01090 info->mIsClaim = is_claim;
01091 info->mRemoveContribution = remove_contribution;
01092 info->mHost = region->getHost();
01093 info->mPrice = mCurrentParcel->getSalePrice();
01094 info->mArea = mCurrentParcel->getArea();
01095
01096 if (!is_claim)
01097 {
01098 info->mParcelID = mCurrentParcel->getLocalID();
01099 }
01100 else
01101 {
01102
01103 LLVector3 west_south_bottom_region = region->getPosRegionFromGlobal( mWestSouth );
01104 LLVector3 east_north_top_region = region->getPosRegionFromGlobal( mEastNorth );
01105
01106 info->mWest = west_south_bottom_region.mV[VX];
01107 info->mSouth = west_south_bottom_region.mV[VY];
01108 info->mEast = east_north_top_region.mV[VX];
01109 info->mNorth = east_north_top_region.mV[VY];
01110 }
01111
01112 return info;
01113 }
01114
01115 void LLViewerParcelMgr::sendParcelBuy(ParcelBuyInfo* info)
01116 {
01117
01118 LLMessageSystem* msg = gMessageSystem;
01119 msg->newMessage(info->mIsClaim ? "ParcelClaim" : "ParcelBuy");
01120 msg->nextBlock("AgentData");
01121 msg->addUUID("AgentID", info->mAgent);
01122 msg->addUUID("SessionID", info->mSession);
01123 msg->nextBlock("Data");
01124 msg->addUUID("GroupID", info->mGroup);
01125 msg->addBOOL("IsGroupOwned", info->mIsGroupOwned);
01126 if (!info->mIsClaim)
01127 {
01128 msg->addBOOL("RemoveContribution", info->mRemoveContribution);
01129 msg->addS32("LocalID", info->mParcelID);
01130 }
01131 msg->addBOOL("Final", TRUE);
01132 if (info->mIsClaim)
01133 {
01134 msg->nextBlock("ParcelData");
01135 msg->addF32("West", info->mWest);
01136 msg->addF32("South", info->mSouth);
01137 msg->addF32("East", info->mEast);
01138 msg->addF32("North", info->mNorth);
01139 }
01140 else
01141 {
01142 msg->nextBlock("ParcelData");
01143 msg->addS32("Price",info->mPrice);
01144 msg->addS32("Area",info->mArea);
01145 }
01146 msg->sendReliable(info->mHost);
01147 }
01148
01149 void LLViewerParcelMgr::deleteParcelBuy(ParcelBuyInfo*& info)
01150 {
01151 delete info;
01152 info = NULL;
01153 }
01154
01155 void LLViewerParcelMgr::sendParcelDeed(const LLUUID& group_id)
01156 {
01157 if (!mSelected || !mCurrentParcel)
01158 {
01159 gViewerWindow->alertXml("CannotDeedLandNothingSelected");
01160 return;
01161 }
01162 if(group_id.isNull())
01163 {
01164 gViewerWindow->alertXml("CannotDeedLandNoGroup");
01165 return;
01166 }
01167 LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
01168 if (!region)
01169 {
01170 gViewerWindow->alertXml("CannotDeedLandNoRegion");
01171 return;
01172 }
01173
01174 LLMessageSystem* msg = gMessageSystem;
01175 msg->newMessage("ParcelDeedToGroup");
01176 msg->nextBlock("AgentData");
01177 msg->addUUID("AgentID", gAgent.getID() );
01178 msg->addUUID("SessionID", gAgent.getSessionID() );
01179 msg->nextBlock("Data");
01180 msg->addUUID("GroupID", group_id );
01181 msg->addS32("LocalID", mCurrentParcel->getLocalID() );
01182
01183 msg->sendReliable( region->getHost() );
01184 }
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225 const LLString& LLViewerParcelMgr::getAgentParcelName() const
01226 {
01227 return mAgentParcel->getName();
01228 }
01229
01230
01231 void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_agent_region)
01232 {
01233 if(!parcel) return;
01234
01235 LLViewerRegion *region = use_agent_region ? gAgent.getRegion() : LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
01236 if (!region) return;
01237
01238
01239 LLSD body;
01240 std::string url = region->getCapability("ParcelPropertiesUpdate");
01241 if (!url.empty())
01242 {
01243
01244 U32 message_flags = 0x01;
01245 body["flags"] = ll_sd_from_U32(message_flags);
01246 parcel->packMessage(body);
01247 llinfos << "Sending parcel properties update via capability to: "
01248 << url << llendl;
01249 LLHTTPClient::post(url, body, new LLHTTPClient::Responder());
01250 }
01251 else
01252 {
01253 LLMessageSystem* msg = gMessageSystem;
01254 msg->newMessageFast(_PREHASH_ParcelPropertiesUpdate);
01255 msg->nextBlockFast(_PREHASH_AgentData);
01256 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01257 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01258 msg->nextBlockFast(_PREHASH_ParcelData);
01259 msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
01260
01261 U32 message_flags = 0x01;
01262 msg->addU32("Flags", message_flags);
01263
01264 parcel->packMessage(msg);
01265
01266 msg->sendReliable( region->getHost() );
01267 }
01268 }
01269
01270
01271 void LLViewerParcelMgr::requestHoverParcelProperties(const LLVector3d& pos)
01272 {
01273 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos );
01274 if (!region)
01275 {
01276 return;
01277 }
01278
01279
01280
01281
01282 LLVector3 wsb_region = region->getPosRegionFromGlobal( pos );
01283
01284 F32 west = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS );
01285 F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS );
01286
01287 F32 east = west + PARCEL_GRID_STEP_METERS;
01288 F32 north = south + PARCEL_GRID_STEP_METERS;
01289
01290
01291 LLMessageSystem *msg = gMessageSystem;
01292 msg->newMessageFast(_PREHASH_ParcelPropertiesRequest);
01293 msg->nextBlockFast(_PREHASH_AgentData);
01294 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01295 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
01296 msg->nextBlockFast(_PREHASH_ParcelData);
01297 msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID );
01298 msg->addF32Fast(_PREHASH_West, west );
01299 msg->addF32Fast(_PREHASH_South, south );
01300 msg->addF32Fast(_PREHASH_East, east );
01301 msg->addF32Fast(_PREHASH_North, north );
01302 msg->addBOOL("SnapSelection", FALSE );
01303 msg->sendReliable( region->getHost() );
01304
01305 mHoverRequestResult = PARCEL_RESULT_NO_DATA;
01306 }
01307
01308
01309
01310 void LLViewerParcelMgr::processParcelOverlay(LLMessageSystem *msg, void **user)
01311 {
01312 if (gNoRender)
01313 {
01314 return;
01315 }
01316
01317
01318 S32 packed_overlay_size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Data);
01319
01320 if (packed_overlay_size == 0)
01321 {
01322 llwarns << "Overlay size 0" << llendl;
01323 return;
01324 }
01325
01326 S32 parcels_per_edge = LLViewerParcelMgr::getInstance()->mParcelsPerEdge;
01327 S32 expected_size = parcels_per_edge * parcels_per_edge / PARCEL_OVERLAY_CHUNKS;
01328 if (packed_overlay_size != expected_size)
01329 {
01330 llwarns << "Got parcel overlay size " << packed_overlay_size
01331 << " expecting " << expected_size << llendl;
01332 return;
01333 }
01334
01335 S32 sequence_id;
01336 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id);
01337 msg->getBinaryDataFast(
01338 _PREHASH_ParcelData,
01339 _PREHASH_Data,
01340 sPackedOverlay,
01341 expected_size);
01342
01343 LLHost host = msg->getSender();
01344 LLViewerRegion *region = LLWorld::getInstance()->getRegion(host);
01345 if (region)
01346 {
01347 region->mParcelOverlay->uncompressLandOverlay( sequence_id, sPackedOverlay );
01348 }
01349 }
01350
01351
01352 void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **user)
01353 {
01354 S32 request_result;
01355 S32 sequence_id;
01356 BOOL snap_selection = FALSE;
01357 S32 self_count = 0;
01358 S32 other_count = 0;
01359 S32 public_count = 0;
01360 S32 local_id;
01361 LLUUID owner_id;
01362 BOOL is_group_owned;
01363 U32 auction_id = 0;
01364 S32 claim_price_per_meter = 0;
01365 S32 rent_price_per_meter = 0;
01366 S32 claim_date = 0;
01367 LLVector3 aabb_min;
01368 LLVector3 aabb_max;
01369 S32 area = 0;
01370 S32 sw_max_prims = 0;
01371 S32 sw_total_prims = 0;
01372
01373 U8 status = 0;
01374 S32 max_prims = 0;
01375 S32 total_prims = 0;
01376 S32 owner_prims = 0;
01377 S32 group_prims = 0;
01378 S32 other_prims = 0;
01379 S32 selected_prims = 0;
01380 F32 parcel_prim_bonus = 1.f;
01381 BOOL region_push_override = false;
01382 BOOL region_deny_anonymous_override = false;
01383 BOOL region_deny_identified_override = false;
01384 BOOL region_deny_transacted_override = false;
01385 BOOL region_deny_age_unverified_override = false;
01386
01387 S32 other_clean_time = 0;
01388
01389 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_RequestResult, request_result );
01390 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SequenceID, sequence_id );
01391
01392 if (request_result == PARCEL_RESULT_NO_DATA)
01393 {
01394
01395 llinfos << "no valid parcel data" << llendl;
01396 return;
01397 }
01398
01399
01400 LLParcel* parcel = NULL;
01401 if (sequence_id == SELECTED_PARCEL_SEQ_ID)
01402 {
01403
01404 LLViewerParcelMgr::getInstance()->mRequestResult = PARCEL_RESULT_SUCCESS;
01405 parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
01406 }
01407 else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
01408 {
01409 LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
01410 parcel = LLViewerParcelMgr::getInstance()->mHoverParcel;
01411 }
01412 else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
01413 sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
01414 sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01415 {
01416 LLViewerParcelMgr::getInstance()->mHoverRequestResult = PARCEL_RESULT_SUCCESS;
01417 parcel = LLViewerParcelMgr::getInstance()->mCollisionParcel;
01418 }
01419 else if (sequence_id == 0 || sequence_id > LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID)
01420 {
01421
01422 LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID = sequence_id;
01423 parcel = LLViewerParcelMgr::getInstance()->mAgentParcel;
01424 }
01425 else
01426 {
01427 llinfos << "out of order agent parcel sequence id " << sequence_id
01428 << " last good " << LLViewerParcelMgr::getInstance()->mAgentParcelSequenceID
01429 << llendl;
01430 return;
01431 }
01432
01433 msg->getBOOL("ParcelData", "SnapSelection", snap_selection);
01434 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelfCount, self_count);
01435 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherCount, other_count);
01436 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_PublicCount, public_count);
01437 msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_LocalID, local_id );
01438 msg->getUUIDFast(_PREHASH_ParcelData, _PREHASH_OwnerID, owner_id);
01439 msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_IsGroupOwned, is_group_owned);
01440 msg->getU32Fast(_PREHASH_ParcelData, _PREHASH_AuctionID, auction_id);
01441 msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimDate, claim_date);
01442 msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_ClaimPrice, claim_price_per_meter);
01443 msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_RentPrice, rent_price_per_meter);
01444 msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMin, aabb_min);
01445 msg->getVector3Fast(_PREHASH_ParcelData, _PREHASH_AABBMax, aabb_max);
01446 msg->getS32Fast( _PREHASH_ParcelData, _PREHASH_Area, area );
01447
01448 msg->getU8("ParcelData", "Status", status);
01449 msg->getS32("ParcelData", "SimWideMaxPrims", sw_max_prims );
01450 msg->getS32("ParcelData", "SimWideTotalPrims", sw_total_prims );
01451 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_MaxPrims, max_prims );
01452 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_TotalPrims, total_prims );
01453 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OwnerPrims, owner_prims );
01454 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_GroupPrims, group_prims );
01455 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_OtherPrims, other_prims );
01456 msg->getS32Fast(_PREHASH_ParcelData, _PREHASH_SelectedPrims, selected_prims );
01457 msg->getF32Fast(_PREHASH_ParcelData, _PREHASH_ParcelPrimBonus, parcel_prim_bonus );
01458 msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionPushOverride, region_push_override );
01459 msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyAnonymous, region_deny_anonymous_override );
01460 msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyIdentified, region_deny_identified_override );
01461 msg->getBOOLFast(_PREHASH_ParcelData, _PREHASH_RegionDenyTransacted, region_deny_transacted_override );
01462 if (msg->getNumberOfBlocksFast(_PREHASH_AgeVerificationBlock))
01463 {
01464
01465 msg->getBOOLFast(_PREHASH_AgeVerificationBlock, _PREHASH_RegionDenyAgeUnverified, region_deny_age_unverified_override );
01466 }
01467
01468 msg->getS32("ParcelData", "OtherCleanTime", other_clean_time );
01469
01470
01471 if (parcel)
01472 {
01473 parcel->init(owner_id,
01474 FALSE, FALSE, FALSE,
01475 claim_date, claim_price_per_meter, rent_price_per_meter,
01476 area, other_prims, parcel_prim_bonus, is_group_owned);
01477 parcel->setLocalID(local_id);
01478 parcel->setAABBMin(aabb_min);
01479 parcel->setAABBMax(aabb_max);
01480
01481 parcel->setAuctionID(auction_id);
01482 parcel->setOwnershipStatus((LLParcel::EOwnershipStatus)status);
01483
01484 parcel->setSimWideMaxPrimCapacity(sw_max_prims);
01485 parcel->setSimWidePrimCount(sw_total_prims);
01486 parcel->setMaxPrimCapacity(max_prims);
01487 parcel->setOwnerPrimCount(owner_prims);
01488 parcel->setGroupPrimCount(group_prims);
01489 parcel->setOtherPrimCount(other_prims);
01490 parcel->setSelectedPrimCount(selected_prims);
01491 parcel->setParcelPrimBonus(parcel_prim_bonus);
01492
01493 parcel->setCleanOtherTime(other_clean_time);
01494 parcel->setRegionPushOverride(region_push_override);
01495 parcel->setRegionDenyAnonymousOverride(region_deny_anonymous_override);
01496 parcel->setRegionDenyAgeUnverifiedOverride(region_deny_age_unverified_override);
01497 parcel->unpackMessage(msg);
01498
01499 if (parcel == LLViewerParcelMgr::getInstance()->mAgentParcel)
01500 {
01501 S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01502 * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01503 / 8;
01504 U8* bitmap = new U8[ bitmap_size ];
01505 msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01506
01507 LLViewerParcelMgr::getInstance()->writeAgentParcelFromBitmap(bitmap);
01508 delete[] bitmap;
01509 }
01510 }
01511
01512
01513 if (sequence_id == SELECTED_PARCEL_SEQ_ID)
01514 {
01515
01516 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedSelfCount = self_count;
01517 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedOtherCount = other_count;
01518 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedPublicCount = public_count;
01519
01520 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mSelectedMultipleOwners =
01521 (request_result == PARCEL_RESULT_MULTIPLE);
01522
01523
01524 LLViewerRegion* region = LLWorld::getInstance()->getRegion( msg->getSender() );
01525 if (region)
01526 {
01527 if (!snap_selection)
01528 {
01529
01530
01531 LLVector3 west_south = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mWestSouth);
01532 LLVector3 east_north = region->getPosRegionFromGlobal(LLViewerParcelMgr::getInstance()->mEastNorth);
01533
01534 LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
01535 LLViewerParcelMgr::getInstance()->writeHighlightSegments(
01536 west_south.mV[VX],
01537 west_south.mV[VY],
01538 east_north.mV[VX],
01539 east_north.mV[VY] );
01540 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = FALSE;
01541 }
01542 else if (0 == local_id)
01543 {
01544
01545 LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
01546 LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
01547
01548 LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
01549 LLViewerParcelMgr::getInstance()->writeHighlightSegments(
01550 aabb_min.mV[VX],
01551 aabb_min.mV[VY],
01552 aabb_max.mV[VX],
01553 aabb_max.mV[VY] );
01554 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
01555 }
01556 else
01557 {
01558 LLViewerParcelMgr::getInstance()->mWestSouth = region->getPosGlobalFromRegion( aabb_min );
01559 LLViewerParcelMgr::getInstance()->mEastNorth = region->getPosGlobalFromRegion( aabb_max );
01560
01561
01562 S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01563 * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01564 / 8;
01565 U8* bitmap = new U8[ bitmap_size ];
01566 msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01567
01568 LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mHighlightSegments);
01569 LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mHighlightSegments );
01570
01571 delete[] bitmap;
01572 bitmap = NULL;
01573
01574 LLViewerParcelMgr::getInstance()->mCurrentParcelSelection->mWholeParcelSelected = TRUE;
01575 }
01576
01577
01578 LLViewerParcelMgr::getInstance()->sendParcelAccessListRequest(AL_ACCESS | AL_BAN);
01579
01580
01581 LLViewerParcelMgr::getInstance()->mSelectedDwell = 0.f;
01582 if (0 != local_id)
01583 {
01584 LLViewerParcelMgr::getInstance()->sendParcelDwellRequest();
01585 }
01586
01587 LLViewerParcelMgr::getInstance()->mSelected = TRUE;
01588 LLViewerParcelMgr::getInstance()->notifyObservers();
01589 }
01590 }
01591 else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID ||
01592 sequence_id == COLLISION_NOT_ON_LIST_PARCEL_SEQ_ID ||
01593 sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01594 {
01595
01596 LLViewerParcelMgr::getInstance()->mRenderCollision = TRUE;
01597 LLViewerParcelMgr::getInstance()->mCollisionTimer.reset();
01598
01599
01600 if (sequence_id == COLLISION_BANNED_PARCEL_SEQ_ID)
01601 {
01602 LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_BANNED;
01603 }
01604 else if (sequence_id == COLLISION_NOT_IN_GROUP_PARCEL_SEQ_ID)
01605 {
01606 LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_IN_GROUP;
01607 }
01608 else
01609 {
01610 LLViewerParcelMgr::getInstance()->mCollisionBanned = BA_NOT_ON_LIST;
01611
01612 }
01613
01614 S32 bitmap_size = LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01615 * LLViewerParcelMgr::getInstance()->mParcelsPerEdge
01616 / 8;
01617 U8* bitmap = new U8[ bitmap_size ];
01618 msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size);
01619
01620 LLViewerParcelMgr::getInstance()->resetSegments(LLViewerParcelMgr::getInstance()->mCollisionSegments);
01621 LLViewerParcelMgr::getInstance()->writeSegmentsFromBitmap( bitmap, LLViewerParcelMgr::getInstance()->mCollisionSegments );
01622
01623 delete[] bitmap;
01624 bitmap = NULL;
01625
01626 }
01627 else if (sequence_id == HOVERED_PARCEL_SEQ_ID)
01628 {
01629 LLViewerRegion *region = LLWorld::getInstance()->getRegion( msg->getSender() );
01630 if (region)
01631 {
01632 LLViewerParcelMgr::getInstance()->mHoverWestSouth = region->getPosGlobalFromRegion( aabb_min );
01633 LLViewerParcelMgr::getInstance()->mHoverEastNorth = region->getPosGlobalFromRegion( aabb_max );
01634 }
01635 else
01636 {
01637 LLViewerParcelMgr::getInstance()->mHoverWestSouth.clearVec();
01638 LLViewerParcelMgr::getInstance()->mHoverEastNorth.clearVec();
01639 }
01640 }
01641 else
01642 {
01643
01644 if (gAudiop)
01645 {
01646 if (parcel)
01647 {
01648 LLString music_url_raw = parcel->getMusicURL();
01649
01650
01651 LLString music_url = music_url_raw;
01652 LLString::trim(music_url);
01653
01654
01655
01656
01657 const char* stream_url = gAudiop->getInternetStreamURL();
01658
01659 if (music_url.empty() || music_url != stream_url)
01660 {
01661
01662 gAudiop->stopInternetStream();
01663
01664
01665 if (music_url.size() > 12)
01666 {
01667 if (music_url.substr(0,7) == "http://")
01668 {
01669 optionally_start_music(music_url);
01670 }
01671 }
01672 else if (gAudiop->getInternetStreamURL()[0])
01673 {
01674 llinfos << "Stopping parcel music" << llendl;
01675 gAudiop->startInternetStream(NULL);
01676 }
01677 }
01678 }
01679 else
01680 {
01681
01682 gAudiop->stopInternetStream();
01683 }
01684 }
01685
01686
01687 LLViewerParcelMedia::update( parcel );
01688 };
01689 }
01690
01691 void optionally_start_music(const LLString& music_url)
01692 {
01693 if (gSavedSettings.getBOOL("AudioStreamingMusic"))
01694 {
01695
01696
01697
01698
01699
01700 if ( gOverlayBar && gOverlayBar->musicPlaying())
01701 {
01702 gAudiop->startInternetStream(music_url.c_str());
01703 }
01704 }
01705 }
01706
01707
01708 void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void **user)
01709 {
01710 LLUUID agent_id;
01711 S32 sequence_id = 0;
01712 U32 message_flags = 0x0;
01713 S32 parcel_id = -1;
01714
01715 msg->getUUIDFast(_PREHASH_Data, _PREHASH_AgentID, agent_id);
01716 msg->getS32Fast( _PREHASH_Data, _PREHASH_SequenceID, sequence_id );
01717 msg->getU32Fast( _PREHASH_Data, _PREHASH_Flags, message_flags);
01718 msg->getS32Fast( _PREHASH_Data, _PREHASH_LocalID, parcel_id);
01719
01720 LLParcel* parcel = LLViewerParcelMgr::getInstance()->mCurrentParcel;
01721 if (!parcel) return;
01722
01723 if (parcel_id != parcel->getLocalID())
01724 {
01725 llwarns << "processParcelAccessListReply for parcel " << parcel_id
01726 << " which isn't the selected parcel " << parcel->getLocalID()<< llendl;
01727 return;
01728 }
01729
01730 if (message_flags & AL_ACCESS)
01731 {
01732 parcel->unpackAccessEntries(msg, &(parcel->mAccessList) );
01733 }
01734 else if (message_flags & AL_BAN)
01735 {
01736 parcel->unpackAccessEntries(msg, &(parcel->mBanList) );
01737 }
01738
01739
01740
01741
01742
01743 LLViewerParcelMgr::getInstance()->notifyObservers();
01744 }
01745
01746
01747
01748 void LLViewerParcelMgr::processParcelDwellReply(LLMessageSystem* msg, void**)
01749 {
01750 LLUUID agent_id;
01751 msg->getUUID("AgentData", "AgentID", agent_id);
01752
01753 S32 local_id;
01754 msg->getS32("Data", "LocalID", local_id);
01755
01756 LLUUID parcel_id;
01757 msg->getUUID("Data", "ParcelID", parcel_id);
01758
01759 F32 dwell;
01760 msg->getF32("Data", "Dwell", dwell);
01761
01762 if (local_id == LLViewerParcelMgr::getInstance()->mCurrentParcel->getLocalID())
01763 {
01764 LLViewerParcelMgr::getInstance()->mSelectedDwell = dwell;
01765 LLViewerParcelMgr::getInstance()->notifyObservers();
01766 }
01767 }
01768
01769
01770 void LLViewerParcelMgr::sendParcelAccessListUpdate(U32 which)
01771 {
01772
01773 LLUUID transactionUUID;
01774 transactionUUID.generate();
01775
01776 if (!mSelected)
01777 {
01778 return;
01779 }
01780
01781 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
01782 if (!region) return;
01783
01784 LLMessageSystem* msg = gMessageSystem;
01785
01786 LLParcel* parcel = mCurrentParcel;
01787 if (!parcel) return;
01788
01789 if (which & AL_ACCESS)
01790 {
01791 S32 count = parcel->mAccessList.size();
01792 S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
01793 S32 sequence_id = 1;
01794 BOOL start_message = TRUE;
01795 BOOL initial = TRUE;
01796
01797 access_map_const_iterator cit = parcel->mAccessList.begin();
01798 access_map_const_iterator end = parcel->mAccessList.end();
01799 while ( (cit != end) || initial )
01800 {
01801 if (start_message)
01802 {
01803 msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
01804 msg->nextBlockFast(_PREHASH_AgentData);
01805 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01806 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
01807 msg->nextBlockFast(_PREHASH_Data);
01808 msg->addU32Fast(_PREHASH_Flags, AL_ACCESS);
01809 msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
01810 msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
01811 msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
01812 msg->addS32Fast(_PREHASH_Sections, num_sections);
01813 start_message = FALSE;
01814
01815 if (initial && (cit == end))
01816 {
01817
01818 msg->nextBlockFast(_PREHASH_List);
01819 msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
01820 msg->addS32Fast(_PREHASH_Time, 0 );
01821 msg->addU32Fast(_PREHASH_Flags, 0 );
01822 }
01823
01824 initial = FALSE;
01825 sequence_id++;
01826
01827 }
01828
01829 while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES))
01830 {
01831
01832 const LLAccessEntry& entry = (*cit).second;
01833
01834 msg->nextBlockFast(_PREHASH_List);
01835 msg->addUUIDFast(_PREHASH_ID, entry.mID );
01836 msg->addS32Fast(_PREHASH_Time, entry.mTime );
01837 msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
01838 ++cit;
01839 }
01840
01841 start_message = TRUE;
01842 msg->sendReliable( region->getHost() );
01843 }
01844 }
01845
01846 if (which & AL_BAN)
01847 {
01848 S32 count = parcel->mBanList.size();
01849 S32 num_sections = (S32) ceil(count/PARCEL_MAX_ENTRIES_PER_PACKET);
01850 S32 sequence_id = 1;
01851 BOOL start_message = TRUE;
01852 BOOL initial = TRUE;
01853
01854 access_map_const_iterator cit = parcel->mBanList.begin();
01855 access_map_const_iterator end = parcel->mBanList.end();
01856 while ( (cit != end) || initial )
01857 {
01858 if (start_message)
01859 {
01860 msg->newMessageFast(_PREHASH_ParcelAccessListUpdate);
01861 msg->nextBlockFast(_PREHASH_AgentData);
01862 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
01863 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() );
01864 msg->nextBlockFast(_PREHASH_Data);
01865 msg->addU32Fast(_PREHASH_Flags, AL_BAN);
01866 msg->addS32(_PREHASH_LocalID, parcel->getLocalID() );
01867 msg->addUUIDFast(_PREHASH_TransactionID, transactionUUID);
01868 msg->addS32Fast(_PREHASH_SequenceID, sequence_id);
01869 msg->addS32Fast(_PREHASH_Sections, num_sections);
01870 start_message = FALSE;
01871
01872 if (initial && (cit == end))
01873 {
01874
01875 msg->nextBlockFast(_PREHASH_List);
01876 msg->addUUIDFast(_PREHASH_ID, LLUUID::null );
01877 msg->addS32Fast(_PREHASH_Time, 0 );
01878 msg->addU32Fast(_PREHASH_Flags, 0 );
01879 }
01880
01881 initial = FALSE;
01882 sequence_id++;
01883
01884 }
01885
01886 while ( (cit != end) && (msg->getCurrentSendTotal() < MTUBYTES))
01887 {
01888 const LLAccessEntry& entry = (*cit).second;
01889
01890 msg->nextBlockFast(_PREHASH_List);
01891 msg->addUUIDFast(_PREHASH_ID, entry.mID );
01892 msg->addS32Fast(_PREHASH_Time, entry.mTime );
01893 msg->addU32Fast(_PREHASH_Flags, entry.mFlags );
01894 ++cit;
01895 }
01896
01897 start_message = TRUE;
01898 msg->sendReliable( region->getHost() );
01899 }
01900 }
01901 }
01902
01903
01904 void LLViewerParcelMgr::deedLandToGroup()
01905 {
01906 std::string group_name;
01907 gCacheName->getGroupName(mCurrentParcel->getGroupID(), group_name);
01908 LLString::format_map_t args;
01909 args["[AREA]"] = llformat("%d", mCurrentParcel->getArea());
01910 args["[GROUP_NAME]"] = group_name;
01911 if(mCurrentParcel->getContributeWithDeed())
01912 {
01913 std::string first_name, last_name;
01914 gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name);
01915 args["[FIRST_NAME]"] = first_name;
01916 args["[LAST_NAME]"] = last_name;
01917 gViewerWindow->alertXml("DeedLandToGroupWithContribution",args, deedAlertCB, NULL);
01918 }
01919 else
01920 {
01921 gViewerWindow->alertXml("DeedLandToGroup",args, deedAlertCB, NULL);
01922 }
01923 }
01924
01925
01926 void LLViewerParcelMgr::deedAlertCB(S32 option, void*)
01927 {
01928 if (option == 0)
01929 {
01930 LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
01931 LLUUID group_id;
01932 if(parcel)
01933 {
01934 group_id = parcel->getGroupID();
01935 }
01936 LLViewerParcelMgr::getInstance()->sendParcelDeed(group_id);
01937 }
01938 }
01939
01940
01941 void LLViewerParcelMgr::startReleaseLand()
01942 {
01943 if (!mSelected)
01944 {
01945 gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
01946 return;
01947 }
01948
01949 if (mRequestResult == PARCEL_RESULT_NO_DATA)
01950 {
01951 gViewerWindow->alertXml("CannotReleaseLandWatingForServer");
01952 return;
01953 }
01954
01955 if (mRequestResult == PARCEL_RESULT_MULTIPLE)
01956 {
01957 gViewerWindow->alertXml("CannotReleaseLandSelected");
01958 return;
01959 }
01960
01961 if (!isParcelOwnedByAgent(mCurrentParcel, GP_LAND_RELEASE)
01962 && !(gAgent.canManageEstate()))
01963 {
01964 gViewerWindow->alertXml("CannotReleaseLandDontOwn");
01965 return;
01966 }
01967
01968 LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
01969 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
01970 if (!region)
01971 {
01972 gViewerWindow->alertXml("CannotReleaseLandRegionNotFound");
01973 return;
01974 }
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986 if (!mCurrentParcelSelection->mWholeParcelSelected)
01987 {
01988 gViewerWindow->alertXml("CannotReleaseLandPartialSelection");
01989 return;
01990 }
01991
01992
01993 LLStringBase<char>::format_map_t args;
01994 args["[AREA]"] = llformat("%d",mCurrentParcel->getArea());
01995 gViewerWindow->alertXml("ReleaseLandWarning", args,
01996 releaseAlertCB, this);
01997 }
01998
01999 bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
02000 {
02001 if (!parcel)
02002 {
02003 return false;
02004 }
02005
02006 if (mSelected && parcel == mCurrentParcel)
02007 {
02008 if (mRequestResult == PARCEL_RESULT_NO_DATA)
02009 {
02010 return false;
02011 }
02012 }
02013
02014 const LLUUID& parcelOwner = parcel->getOwnerID();
02015 const LLUUID& authorizeBuyer = parcel->getAuthorizedBuyerID();
02016
02017 if (parcel->isPublic())
02018 {
02019 return true;
02020 }
02021
02022 bool isForSale = parcel->getForSale()
02023 && ((parcel->getSalePrice() > 0) || (authorizeBuyer.notNull()));
02024
02025 bool isEmpowered
02026 = forGroup ? gAgent.hasPowerInActiveGroup(GP_LAND_DEED) == TRUE : true;
02027
02028 bool isOwner
02029 = parcelOwner == (forGroup ? gAgent.getGroupID() : gAgent.getID());
02030
02031 bool isAuthorized
02032 = (authorizeBuyer.isNull() || (gAgent.getID() == authorizeBuyer));
02033
02034 return isForSale && !isOwner && isAuthorized && isEmpowered;
02035 }
02036
02037
02038 void LLViewerParcelMgr::startBuyLand(BOOL is_for_group)
02039 {
02040 LLFloaterBuyLand::buyLand(getSelectionRegion(), mCurrentParcelSelection, is_for_group == TRUE);
02041 }
02042
02043 void LLViewerParcelMgr::startSellLand()
02044 {
02045 LLFloaterSellLand::sellLand(getSelectionRegion(), mCurrentParcelSelection);
02046 }
02047
02048 void LLViewerParcelMgr::startDivideLand()
02049 {
02050 if (!mSelected)
02051 {
02052 gViewerWindow->alertXml("CannotDivideLandNothingSelected");
02053 return;
02054 }
02055
02056 if (mCurrentParcelSelection->mWholeParcelSelected)
02057 {
02058 gViewerWindow->alertXml("CannotDivideLandPartialSelection");
02059 return;
02060 }
02061
02062 gViewerWindow->alertXml("LandDivideWarning",
02063 callbackDivideLand,
02064 this);
02065 }
02066
02067
02068 void LLViewerParcelMgr::callbackDivideLand(S32 option, void* data)
02069 {
02070 LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
02071
02072 LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
02073 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
02074 if (!region)
02075 {
02076 gViewerWindow->alertXml("CannotDivideLandNoRegion");
02077 return;
02078 }
02079
02080 if (0 == option)
02081 {
02082 LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
02083 LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
02084
02085 LLMessageSystem* msg = gMessageSystem;
02086 msg->newMessage("ParcelDivide");
02087 msg->nextBlock("AgentData");
02088 msg->addUUID("AgentID", gAgent.getID());
02089 msg->addUUID("SessionID", gAgent.getSessionID());
02090 msg->nextBlock("ParcelData");
02091 msg->addF32("West", west_south.mV[VX]);
02092 msg->addF32("South", west_south.mV[VY]);
02093 msg->addF32("East", east_north.mV[VX]);
02094 msg->addF32("North", east_north.mV[VY]);
02095 msg->sendReliable(region->getHost());
02096 }
02097 }
02098
02099
02100 void LLViewerParcelMgr::startJoinLand()
02101 {
02102 if (!mSelected)
02103 {
02104 gViewerWindow->alertXml("CannotJoinLandNothingSelected");
02105 return;
02106 }
02107
02108 if (mCurrentParcelSelection->mWholeParcelSelected)
02109 {
02110 gViewerWindow->alertXml("CannotJoinLandEntireParcelSelected");
02111 return;
02112 }
02113
02114 if (!mCurrentParcelSelection->mSelectedMultipleOwners)
02115 {
02116 gViewerWindow->alertXml("CannotJoinLandSelection");
02117 return;
02118 }
02119
02120 gViewerWindow->alertXml("JoinLandWarning",
02121 callbackJoinLand,
02122 this);
02123 }
02124
02125
02126 void LLViewerParcelMgr::callbackJoinLand(S32 option, void* data)
02127 {
02128 LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
02129
02130 LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
02131 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
02132 if (!region)
02133 {
02134 gViewerWindow->alertXml("CannotJoinLandNoRegion");
02135 return;
02136 }
02137
02138 if (0 == option)
02139 {
02140 LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
02141 LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
02142
02143 LLMessageSystem* msg = gMessageSystem;
02144 msg->newMessage("ParcelJoin");
02145 msg->nextBlock("AgentData");
02146 msg->addUUID("AgentID", gAgent.getID());
02147 msg->addUUID("SessionID", gAgent.getSessionID());
02148 msg->nextBlock("ParcelData");
02149 msg->addF32("West", west_south.mV[VX]);
02150 msg->addF32("South", west_south.mV[VY]);
02151 msg->addF32("East", east_north.mV[VX]);
02152 msg->addF32("North", east_north.mV[VY]);
02153 msg->sendReliable(region->getHost());
02154 }
02155 }
02156
02157
02158 void LLViewerParcelMgr::startDeedLandToGroup()
02159 {
02160 if (!mSelected || !mCurrentParcel)
02161 {
02162 gViewerWindow->alertXml("CannotDeedLandNothingSelected");
02163 return;
02164 }
02165
02166 if (mRequestResult == PARCEL_RESULT_NO_DATA)
02167 {
02168 gViewerWindow->alertXml("CannotDeedLandWaitingForServer");
02169 return;
02170 }
02171
02172 if (mRequestResult == PARCEL_RESULT_MULTIPLE)
02173 {
02174 gViewerWindow->alertXml("CannotDeedLandMultipleSelected");
02175 return;
02176 }
02177
02178 LLVector3d parcel_center = (mWestSouth + mEastNorth) / 2.0;
02179 LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
02180 if (!region)
02181 {
02182 gViewerWindow->alertXml("CannotDeedLandNoRegion");
02183 return;
02184 }
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200 deedLandToGroup();
02201 }
02202 void LLViewerParcelMgr::reclaimParcel()
02203 {
02204 LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
02205 LLViewerRegion* regionp = LLViewerParcelMgr::getInstance()->getSelectionRegion();
02206 if(parcel && parcel->getOwnerID().notNull()
02207 && (parcel->getOwnerID() != gAgent.getID())
02208 && regionp && (regionp->getOwner() == gAgent.getID()))
02209 {
02210 LLMessageSystem* msg = gMessageSystem;
02211 msg->newMessage("ParcelReclaim");
02212 msg->nextBlock("AgentData");
02213 msg->addUUID("AgentID", gAgent.getID());
02214 msg->addUUID("SessionID", gAgent.getSessionID());
02215 msg->nextBlock("Data");
02216 msg->addS32("LocalID", parcel->getLocalID());
02217 msg->sendReliable(regionp->getHost());
02218 }
02219 }
02220
02221
02222 void LLViewerParcelMgr::releaseAlertCB(S32 option, void *)
02223 {
02224 if (option == 0)
02225 {
02226
02227 LLViewerParcelMgr::getInstance()->sendParcelRelease();
02228 }
02229 }
02230
02231 void LLViewerParcelMgr::buyPass()
02232 {
02233 LLParcel* parcel = getParcelSelection()->getParcel();
02234 if (!parcel) return;
02235
02236 LLViewerRegion* region = getSelectionRegion();
02237 if (!region) return;
02238
02239 LLMessageSystem* msg = gMessageSystem;
02240 msg->newMessageFast(_PREHASH_ParcelBuyPass);
02241 msg->nextBlock("AgentData");
02242 msg->addUUID("AgentID", gAgent.getID());
02243 msg->addUUID("SessionID", gAgent.getSessionID());
02244 msg->nextBlockFast(_PREHASH_ParcelData);
02245 msg->addS32Fast(_PREHASH_LocalID, parcel->getLocalID() );
02246 msg->sendReliable( region->getHost() );
02247 }
02248
02249
02250 BOOL LLViewerParcelMgr::isCollisionBanned()
02251 {
02252 if ((mCollisionBanned == BA_ALLOWED) || (mCollisionBanned == BA_NOT_ON_LIST) || (mCollisionBanned == BA_NOT_IN_GROUP))
02253 return FALSE;
02254 else
02255 return TRUE;
02256 }
02257
02258
02259
02260 BOOL LLViewerParcelMgr::isParcelOwnedByAgent(const LLParcel* parcelp, U64 group_proxy_power)
02261 {
02262 if (!parcelp)
02263 {
02264 return FALSE;
02265 }
02266
02267
02268 if (gAgent.isGodlike())
02269 {
02270 return TRUE;
02271 }
02272
02273
02274 if (parcelp->getOwnerID() == gAgent.getID())
02275 {
02276 return TRUE;
02277 }
02278
02279
02280 if (parcelp->isPublic())
02281 {
02282 return FALSE;
02283 }
02284
02285
02286
02287 return gAgent.hasPowerInGroup(parcelp->getOwnerID(), group_proxy_power);
02288 }
02289
02290
02291
02292 BOOL LLViewerParcelMgr::isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power)
02293 {
02294
02295 BOOL rv = FALSE;
02296 if (parcelp)
02297 {
02298
02299
02300 rv = isParcelOwnedByAgent(parcelp, group_proxy_power);
02301
02302
02303 if( (gAgent.getID() == parcelp->getOwnerID())
02304 && !gAgent.isGodlike()
02305 && (parcelp->getOwnershipStatus() != LLParcel::OS_LEASED) )
02306 {
02307 rv = FALSE;
02308 }
02309 }
02310 return rv;
02311 }
02312
02313 void sanitize_corners(const LLVector3d &corner1,
02314 const LLVector3d &corner2,
02315 LLVector3d &west_south_bottom,
02316 LLVector3d &east_north_top)
02317 {
02318 west_south_bottom.mdV[VX] = llmin( corner1.mdV[VX], corner2.mdV[VX] );
02319 west_south_bottom.mdV[VY] = llmin( corner1.mdV[VY], corner2.mdV[VY] );
02320 west_south_bottom.mdV[VZ] = llmin( corner1.mdV[VZ], corner2.mdV[VZ] );
02321
02322 east_north_top.mdV[VX] = llmax( corner1.mdV[VX], corner2.mdV[VX] );
02323 east_north_top.mdV[VY] = llmax( corner1.mdV[VY], corner2.mdV[VY] );
02324 east_north_top.mdV[VZ] = llmax( corner1.mdV[VZ], corner2.mdV[VZ] );
02325 }
02326
02327
02328 void LLViewerParcelMgr::cleanupGlobals()
02329 {
02330 LLParcelSelection::sNullSelection = NULL;
02331 }
02332
02333 LLViewerImage* LLViewerParcelMgr::getBlockedImage() const
02334 {
02335 return sBlockedImage;
02336 }
02337
02338 LLViewerImage* LLViewerParcelMgr::getPassImage() const
02339 {
02340 return sPassImage;
02341 }