aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llagent.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llagent.cpp')
-rw-r--r--linden/indra/newview/llagent.cpp335
1 files changed, 274 insertions, 61 deletions
diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp
index 1193d22..b3321fc 100644
--- a/linden/indra/newview/llagent.cpp
+++ b/linden/indra/newview/llagent.cpp
@@ -192,6 +192,8 @@ const F32 OBJECT_MIN_ZOOM = 0.02f;
192const F32 APPEARANCE_MIN_ZOOM = 0.39f; 192const F32 APPEARANCE_MIN_ZOOM = 0.39f;
193const F32 APPEARANCE_MAX_ZOOM = 8.f; 193const F32 APPEARANCE_MAX_ZOOM = 8.f;
194 194
195const F32 DIST_FUDGE = 16.f; // meters
196
195// fidget constants 197// fidget constants
196const F32 MIN_FIDGET_TIME = 8.f; // seconds 198const F32 MIN_FIDGET_TIME = 8.f; // seconds
197const F32 MAX_FIDGET_TIME = 20.f; // seconds 199const F32 MAX_FIDGET_TIME = 20.f; // seconds
@@ -216,6 +218,7 @@ LLAgent gAgent;
216// 218//
217// Statics 219// Statics
218// 220//
221BOOL LLAgent::sPhantom = FALSE;
219 222
220const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; 223const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;
221 224
@@ -452,6 +455,10 @@ void LLAgent::init()
452//----------------------------------------------------------------------------- 455//-----------------------------------------------------------------------------
453void LLAgent::cleanup() 456void LLAgent::cleanup()
454{ 457{
458 mInitialized = FALSE;
459 mWearablesLoaded = FALSE;
460 mShowAvatar = TRUE;
461
455 setSitCamera(LLUUID::null); 462 setSitCamera(LLUUID::null);
456 mAvatarObject = NULL; 463 mAvatarObject = NULL;
457 if(mLookAt) 464 if(mLookAt)
@@ -751,6 +758,9 @@ void LLAgent::movePitch(S32 direction)
751// Does this parcel allow you to fly? 758// Does this parcel allow you to fly?
752BOOL LLAgent::canFly() 759BOOL LLAgent::canFly()
753{ 760{
761// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c)
762 if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY)) return FALSE;
763// [/RLVa:KB]
754 if (isGodlike()) return TRUE; 764 if (isGodlike()) return TRUE;
755 765
756 LLViewerRegion* regionp = getRegion(); 766 LLViewerRegion* regionp = getRegion();
@@ -790,6 +800,13 @@ void LLAgent::setFlying(BOOL fly)
790 800
791 if (fly) 801 if (fly)
792 { 802 {
803// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0c)
804 if (gRlvHandler.hasBehaviour(RLV_BHVR_FLY))
805 {
806 return;
807 }
808// [/RLVa:KB]
809
793 BOOL was_flying = getFlying(); 810 BOOL was_flying = getFlying();
794 if (!canFly() && !was_flying) 811 if (!canFly() && !was_flying)
795 { 812 {
@@ -829,6 +846,35 @@ void LLAgent::toggleFlying()
829 846
830 847
831//----------------------------------------------------------------------------- 848//-----------------------------------------------------------------------------
849// togglePhantom()
850//-----------------------------------------------------------------------------
851void LLAgent::togglePhantom()
852{
853 BOOL phan = !(sPhantom);
854
855 setPhantom( phan );
856}
857
858
859//-----------------------------------------------------------------------------
860// setPhantom() lgg
861//-----------------------------------------------------------------------------
862void LLAgent::setPhantom(BOOL phantom)
863{
864 sPhantom = phantom;
865}
866
867
868//-----------------------------------------------------------------------------
869// getPhantom() lgg
870//-----------------------------------------------------------------------------
871BOOL LLAgent::getPhantom()
872{
873 return sPhantom;
874}
875
876
877//-----------------------------------------------------------------------------
832// setRegion() 878// setRegion()
833//----------------------------------------------------------------------------- 879//-----------------------------------------------------------------------------
834void LLAgent::setRegion(LLViewerRegion *regionp) 880void LLAgent::setRegion(LLViewerRegion *regionp)
@@ -1670,6 +1716,10 @@ F32 LLAgent::getCameraZoomFraction()
1670 // already [0,1] 1716 // already [0,1]
1671 return mHUDTargetZoom; 1717 return mHUDTargetZoom;
1672 } 1718 }
1719 else if (gSavedSettings.getBOOL("DisableCameraConstraints"))
1720 {
1721 return mCameraZoomFraction;
1722 }
1673 else if (mFocusOnAvatar && cameraThirdPerson()) 1723 else if (mFocusOnAvatar && cameraThirdPerson())
1674 { 1724 {
1675 return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f); 1725 return clamp_rescale(mCameraZoomFraction, MIN_ZOOM_FRACTION, MAX_ZOOM_FRACTION, 1.f, 0.f);
@@ -1682,7 +1732,6 @@ F32 LLAgent::getCameraZoomFraction()
1682 else 1732 else
1683 { 1733 {
1684 F32 min_zoom; 1734 F32 min_zoom;
1685 const F32 DIST_FUDGE = 16.f; // meters
1686 F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 1735 F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
1687 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE, 1736 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
1688 MAX_CAMERA_DISTANCE_FROM_AGENT); 1737 MAX_CAMERA_DISTANCE_FROM_AGENT);
@@ -1731,10 +1780,9 @@ void LLAgent::setCameraZoomFraction(F32 fraction)
1731 else 1780 else
1732 { 1781 {
1733 F32 min_zoom = LAND_MIN_ZOOM; 1782 F32 min_zoom = LAND_MIN_ZOOM;
1734 const F32 DIST_FUDGE = 16.f; // meters
1735 F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE, 1783 F32 max_zoom = llmin(mDrawDistance - DIST_FUDGE,
1736 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE, 1784 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE,
1737 MAX_CAMERA_DISTANCE_FROM_AGENT); 1785 MAX_CAMERA_DISTANCE_FROM_AGENT);
1738 1786
1739 if (mFocusObject.notNull()) 1787 if (mFocusObject.notNull())
1740 { 1788 {
@@ -1753,7 +1801,14 @@ void LLAgent::setCameraZoomFraction(F32 fraction)
1753 1801
1754 LLVector3d camera_offset_dir = mCameraFocusOffsetTarget; 1802 LLVector3d camera_offset_dir = mCameraFocusOffsetTarget;
1755 camera_offset_dir.normalize(); 1803 camera_offset_dir.normalize();
1756 mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom); 1804 if (gSavedSettings.getBOOL("DisableCameraConstraints"))
1805 {
1806 mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 262140.f, 1.f, min_zoom);
1807 }
1808 else
1809 {
1810 mCameraFocusOffsetTarget = camera_offset_dir * rescale(fraction, 0.f, 1.f, max_zoom, min_zoom);
1811 }
1757 } 1812 }
1758 startCameraAnimation(); 1813 startCameraAnimation();
1759} 1814}
@@ -1852,29 +1907,32 @@ void LLAgent::cameraZoomIn(const F32 fraction)
1852 } 1907 }
1853 } 1908 }
1854 1909
1855 new_distance = llmax(new_distance, min_zoom);
1856
1857 // Don't zoom too far back 1910 // Don't zoom too far back
1858 const F32 DIST_FUDGE = 16.f; // meters 1911 // Actually, let's when disable camera constraints is active -- McCabe
1859 F32 max_distance = llmin(mDrawDistance - DIST_FUDGE, 1912 if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
1860 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
1861
1862 if (new_distance > max_distance)
1863 { 1913 {
1864 new_distance = max_distance; 1914 new_distance = llmax(new_distance, min_zoom);
1865 1915
1866 /* 1916 F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
1867 // Unless camera is unlocked 1917 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
1868 if (!LLViewerCamera::sDisableCameraConstraints) 1918
1919 if (new_distance > max_distance)
1869 { 1920 {
1870 return; 1921 new_distance = max_distance;
1922
1923 /*
1924 // Unless camera is unlocked
1925 if (!LLViewerCamera::sDisableCameraConstraints)
1926 {
1927 return;
1928 }
1929 */
1871 } 1930 }
1872 */
1873 }
1874 1931
1875 if( cameraCustomizeAvatar() ) 1932 if( cameraCustomizeAvatar() )
1876 { 1933 {
1877 new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM ); 1934 new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
1935 }
1878 } 1936 }
1879 1937
1880 mCameraFocusOffsetTarget = new_distance * camera_offset_unit; 1938 mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
@@ -1905,40 +1963,41 @@ void LLAgent::cameraOrbitIn(const F32 meters)
1905 LLVector3d camera_offset_unit(mCameraFocusOffsetTarget); 1963 LLVector3d camera_offset_unit(mCameraFocusOffsetTarget);
1906 F32 current_distance = (F32)camera_offset_unit.normalize(); 1964 F32 current_distance = (F32)camera_offset_unit.normalize();
1907 F32 new_distance = current_distance - meters; 1965 F32 new_distance = current_distance - meters;
1908 F32 min_zoom = LAND_MIN_ZOOM; 1966
1909 1967 // Don't zoom too far back
1910 // Don't move through focus point 1968 // Actually, let's when disable camera constraints is active -- McCabe
1911 if (mFocusObject.notNull()) 1969 if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
1912 { 1970 {
1913 if (mFocusObject->isAvatar()) 1971 F32 min_zoom = LAND_MIN_ZOOM;
1914 { 1972 F32 max_distance;
1915 min_zoom = AVATAR_MIN_ZOOM; 1973
1916 } 1974 // Don't move through focus point
1917 else 1975 if (mFocusObject.notNull())
1918 { 1976 {
1919 min_zoom = OBJECT_MIN_ZOOM; 1977 if (mFocusObject->isAvatar())
1978 {
1979 min_zoom = AVATAR_MIN_ZOOM;
1980 }
1981 else
1982 {
1983 min_zoom = OBJECT_MIN_ZOOM;
1984 }
1920 } 1985 }
1921 }
1922 1986
1923 new_distance = llmax(new_distance, min_zoom); 1987 new_distance = llmax(new_distance, min_zoom);
1924 1988
1925 // Don't zoom too far back 1989 max_distance = llmin(mDrawDistance - DIST_FUDGE,
1926 const F32 DIST_FUDGE = 16.f; // meters 1990 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
1927 F32 max_distance = llmin(mDrawDistance - DIST_FUDGE,
1928 LLWorld::getInstance()->getRegionWidthInMeters() - DIST_FUDGE );
1929 1991
1930 if (new_distance > max_distance) 1992 if (new_distance > max_distance)
1931 {
1932 // Unless camera is unlocked
1933 if (!gSavedSettings.getBOOL("DisableCameraConstraints"))
1934 { 1993 {
1935 return; 1994 return;
1936 } 1995 }
1937 }
1938 1996
1939 if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() ) 1997 if( CAMERA_MODE_CUSTOMIZE_AVATAR == getCameraMode() )
1940 { 1998 {
1941 new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM ); 1999 new_distance = llclamp( new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM );
2000 }
1942 } 2001 }
1943 2002
1944 // Compute new camera offset 2003 // Compute new camera offset
@@ -4214,6 +4273,13 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
4214 return; 4273 return;
4215 } 4274 }
4216 4275
4276// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g)
4277 if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) )
4278 {
4279 return;
4280 }
4281// [/RLVa:KB]
4282
4217 setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up 4283 setControlFlags(AGENT_CONTROL_STAND_UP); // force stand up
4218 gViewerWindow->getWindow()->resetBusyCount(); 4284 gViewerWindow->getWindow()->resetBusyCount();
4219 4285
@@ -5142,6 +5208,14 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO
5142// utility to build a location string 5208// utility to build a location string
5143void LLAgent::buildLocationString(std::string& str) 5209void LLAgent::buildLocationString(std::string& str)
5144{ 5210{
5211// [RLVa:KB] - Checked: 2009-07-04 (RLVa-1.0.0a)
5212 if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
5213 {
5214 str = rlv_handler_t::cstrHidden;
5215 return;
5216 }
5217// [/RLVa:KB]
5218
5145 const LLVector3& agent_pos_region = getPositionAgent(); 5219 const LLVector3& agent_pos_region = getPositionAgent();
5146 S32 pos_x = S32(agent_pos_region.mV[VX]); 5220 S32 pos_x = S32(agent_pos_region.mV[VX]);
5147 S32 pos_y = S32(agent_pos_region.mV[VY]); 5221 S32 pos_y = S32(agent_pos_region.mV[VY]);
@@ -6035,6 +6109,15 @@ void LLAgent::teleportRequest(
6035// Landmark ID = LLUUID::null means teleport home 6109// Landmark ID = LLUUID::null means teleport home
6036void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) 6110void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id)
6037{ 6111{
6112// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d)
6113 if ( (rlv_handler_t::isEnabled()) &&
6114 ( (gRlvHandler.hasBehaviour(RLV_BHVR_TPLM)) ||
6115 ((gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting)) ))
6116 {
6117 return;
6118 }
6119// [/RLVa:KB]
6120
6038 LLViewerRegion *regionp = getRegion(); 6121 LLViewerRegion *regionp = getRegion();
6039 if(regionp && teleportCore()) 6122 if(regionp && teleportCore())
6040 { 6123 {
@@ -6099,6 +6182,17 @@ void LLAgent::teleportCancel()
6099 6182
6100void LLAgent::teleportViaLocation(const LLVector3d& pos_global) 6183void LLAgent::teleportViaLocation(const LLVector3d& pos_global)
6101{ 6184{
6185// [RLVa:KB] - Alternate: Snowglobe-1.0 | Checked: 2009-07-07 (RLVa-1.0.0d)
6186 // If we're getting teleported due to @tpto we should disregard any @tploc=n or @unsit=n restrictions from the same object
6187 if ( (rlv_handler_t::isEnabled()) &&
6188 ( (gRlvHandler.hasBehaviourExcept(RLV_BHVR_TPLOC, gRlvHandler.getCurrentObject())) ||
6189 ( (mAvatarObject.notNull()) && (mAvatarObject->mIsSitting) &&
6190 (gRlvHandler.hasBehaviourExcept(RLV_BHVR_UNSIT, gRlvHandler.getCurrentObject()))) ) )
6191 {
6192 return;
6193 }
6194// [/RLVa:KB]
6195
6102 LLViewerRegion* regionp = getRegion(); 6196 LLViewerRegion* regionp = getRegion();
6103 LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); 6197 LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global);
6104 if(regionp && info) 6198 if(regionp && info)
@@ -6175,6 +6269,13 @@ void LLAgent::setTeleportState(ETeleportState state)
6175 // We're outa here. Save "back" slurl. 6269 // We're outa here. Save "back" slurl.
6176 mTeleportSourceSLURL = getSLURL(); 6270 mTeleportSourceSLURL = getSLURL();
6177 } 6271 }
6272
6273// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b
6274 if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) )
6275 {
6276 gRlvHandler.setCanCancelTp(true);
6277 }
6278// [/RLVa:KB]
6178} 6279}
6179 6280
6180void LLAgent::stopCurrentAnimations() 6281void LLAgent::stopCurrentAnimations()
@@ -6742,11 +6843,19 @@ BOOL LLAgent::isWearingItem( const LLUUID& item_id )
6742// static 6843// static
6743void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data ) 6844void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void** user_data )
6744{ 6845{
6846 if (gNoRender)
6847 {
6848 return;
6849 }
6850
6745 // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates 6851 // We should only receive this message a single time. Ignore subsequent AgentWearablesUpdates
6746 // that may result from AgentWearablesRequest having been sent more than once. 6852 // that may result from AgentWearablesRequest having been sent more than once.
6853 // If we do this, then relogging won't work. - Gigs
6854 /*
6747 static bool first = true; 6855 static bool first = true;
6748 if (!first) return; 6856 if (!first) return;
6749 first = false; 6857 first = false;
6858 */
6750 6859
6751 LLUUID agent_id; 6860 LLUUID agent_id;
6752 gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id ); 6861 gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
@@ -6804,10 +6913,17 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
6804 } 6913 }
6805 6914
6806 // now that we have the asset ids...request the wearable assets 6915 // now that we have the asset ids...request the wearable assets
6916// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6917 LLInventoryFetchObserver::item_ref_t rlvItems;
6918// [/RLVa:KB]
6807 for( i = 0; i < WT_COUNT; i++ ) 6919 for( i = 0; i < WT_COUNT; i++ )
6808 { 6920 {
6809 if( !gAgent.mWearableEntry[i].mItemID.isNull() ) 6921 if( !gAgent.mWearableEntry[i].mItemID.isNull() )
6810 { 6922 {
6923// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6924 if (rlv_handler_t::isEnabled())
6925 rlvItems.push_back(gAgent.mWearableEntry[i].mItemID);
6926// [/RLVa:KB]
6811 gWearableList.getAsset( 6927 gWearableList.getAsset(
6812 asset_id_array[i], 6928 asset_id_array[i],
6813 LLStringUtil::null, 6929 LLStringUtil::null,
@@ -6815,6 +6931,15 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
6815 LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i ); 6931 LLAgent::onInitialWearableAssetArrived, (void*)(intptr_t)i );
6816 } 6932 }
6817 } 6933 }
6934
6935// [RLVa:KB] - Checked: 2009-08-08 (RLVa-1.0.1g) | Added: RLVa-1.0.1g
6936 // TODO-RLVa: checking that we're in STATE_STARTED is probably not needed, but leave it until we can be absolutely sure
6937 if ( (rlv_handler_t::isEnabled()) && (LLStartUp::getStartupState() == STATE_STARTED) )
6938 {
6939 RlvCurrentlyWorn f;
6940 f.fetchItems(rlvItems);
6941 }
6942// [/RLVa:KB]
6818 } 6943 }
6819} 6944}
6820 6945
@@ -7314,6 +7439,13 @@ void LLAgent::removeWearable( EWearableType type )
7314 return; 7439 return;
7315 } 7440 }
7316 7441
7442// [RLVa:KB] - Version: 1.22.11 | Checked: 2009-07-07 (RLVa-1.0.0d)
7443 if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.isRemovable(type)) )
7444 {
7445 return;
7446 }
7447// [/RLVa:KB]
7448
7317 if( old_wearable ) 7449 if( old_wearable )
7318 { 7450 {
7319 if( old_wearable->isDirty() ) 7451 if( old_wearable->isDirty() )
@@ -7440,15 +7572,17 @@ void LLAgent::setWearableOutfit(
7440 wearables_to_remove[WT_SKIN] = FALSE; 7572 wearables_to_remove[WT_SKIN] = FALSE;
7441 wearables_to_remove[WT_HAIR] = FALSE; 7573 wearables_to_remove[WT_HAIR] = FALSE;
7442 wearables_to_remove[WT_EYES] = FALSE; 7574 wearables_to_remove[WT_EYES] = FALSE;
7443 wearables_to_remove[WT_SHIRT] = remove; 7575// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.2a
7444 wearables_to_remove[WT_PANTS] = remove; 7576 wearables_to_remove[WT_SHIRT] = remove && gRlvHandler.isRemovable(WT_SHIRT);
7445 wearables_to_remove[WT_SHOES] = remove; 7577 wearables_to_remove[WT_PANTS] = remove && gRlvHandler.isRemovable(WT_PANTS);
7446 wearables_to_remove[WT_SOCKS] = remove; 7578 wearables_to_remove[WT_SHOES] = remove && gRlvHandler.isRemovable(WT_SHOES);
7447 wearables_to_remove[WT_JACKET] = remove; 7579 wearables_to_remove[WT_SOCKS] = remove && gRlvHandler.isRemovable(WT_SOCKS);
7448 wearables_to_remove[WT_GLOVES] = remove; 7580 wearables_to_remove[WT_JACKET] = remove && gRlvHandler.isRemovable(WT_JACKET);
7449 wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove; 7581 wearables_to_remove[WT_GLOVES] = remove && gRlvHandler.isRemovable(WT_GLOVES);
7450 wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove; 7582 wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERSHIRT);
7451 wearables_to_remove[WT_SKIRT] = remove; 7583 wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) && remove && gRlvHandler.isRemovable(WT_UNDERPANTS);
7584 wearables_to_remove[WT_SKIRT] = remove && gRlvHandler.isRemovable(WT_SKIRT);
7585// [/RLVa:KB]
7452 7586
7453 S32 count = wearables.count(); 7587 S32 count = wearables.count();
7454 llassert( items.count() == count ); 7588 llassert( items.count() == count );
@@ -7538,6 +7672,15 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
7538 EWearableType type = new_wearable->getType(); 7672 EWearableType type = new_wearable->getType();
7539 7673
7540 LLWearable* old_wearable = mWearableEntry[ type ].mWearable; 7674 LLWearable* old_wearable = mWearableEntry[ type ].mWearable;
7675
7676// [RLVa:KB] - Checked: 2009-07-07 (RLVa-1.0.0d)
7677 // Block if: we can't wear on that layer; or we're already wearing something there we can't take off
7678 if ( (rlv_handler_t::isEnabled()) && ((!gRlvHandler.isWearable(type)) || ((old_wearable) && (!gRlvHandler.isRemovable(type)))) )
7679 {
7680 return;
7681 }
7682// [/RLVa:KB]
7683
7541 if( old_wearable ) 7684 if( old_wearable )
7542 { 7685 {
7543 const LLUUID& old_item_id = mWearableEntry[ type ].mItemID; 7686 const LLUUID& old_item_id = mWearableEntry[ type ].mItemID;
@@ -7750,10 +7893,13 @@ void LLAgent::userRemoveAllAttachments( void* userdata )
7750 return; 7893 return;
7751 } 7894 }
7752 7895
7753 gMessageSystem->newMessage("ObjectDetach"); 7896// [RLVa:KB] - Checked: 2009-07-06 (RLVa-1.0.0c) | Added: RLVa-0.2.0c
7754 gMessageSystem->nextBlockFast(_PREHASH_AgentData); 7897 // NOTE-RLVa: This function is called from inside RlvHandler as well, hence the rather heavy modifications
7755 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); 7898 std::list<U32> rlvAttachments;
7756 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); 7899 // TODO-RLVa: Once we have the improved "removeWearable" logic implemented we can just get rid of the whole "rlvCompFolders" hassle
7900 #ifdef RLV_EXPERIMENTAL_COMPOSITES
7901 std::list<LLUUID> rlvCompFolders;
7902 #endif // RLV_EXPERIMENTAL_COMPOSITES
7757 7903
7758 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin(); 7904 for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
7759 iter != avatarp->mAttachmentPoints.end(); ) 7905 iter != avatarp->mAttachmentPoints.end(); )
@@ -7763,11 +7909,78 @@ void LLAgent::userRemoveAllAttachments( void* userdata )
7763 LLViewerObject* objectp = attachment->getObject(); 7909 LLViewerObject* objectp = attachment->getObject();
7764 if (objectp) 7910 if (objectp)
7765 { 7911 {
7912 if (rlv_handler_t::isEnabled())
7913 {
7914 if (!gRlvHandler.isDetachable(curiter->first))
7915 continue;
7916
7917 // Check if we're being called in response to an RLV command (that would be @detach=force)
7918 if ( (gRlvHandler.getCurrentCommand()) && (attachment->getItemID().notNull()) )
7919 {
7920 if (!gRlvHandler.isStrippable(attachment->getItemID())) // "nostrip" can be taken off by the user but not @detach
7921 continue;
7922
7923 #ifdef RLV_EXPERIMENTAL_COMPOSITES
7924 LLViewerInventoryCategory* pFolder;
7925 if (gRlvHandler.getCompositeInfo(attachment->getItemID(), NULL, &pFolder))
7926 {
7927 #ifdef RLV_EXPERIMENTAL_COMPOSITE_LOCKING
7928 if (!gRlvHandler.canTakeOffComposite(pFolder))
7929 continue;
7930 #endif // RLV_EXPERIMENTAL_COMPOSITE_LOCKING
7931
7932 // The attachment belongs to a composite folder so there may be additional things we need to take off
7933 if (std::find(rlvCompFolders.begin(), rlvCompFolders.end(), pFolder->getUUID()) != rlvCompFolders.end())
7934 rlvCompFolders.push_back(pFolder->getUUID());
7935 }
7936 #endif // RLV_EXPERIMENTAL_COMPOSITES
7937 }
7938 }
7939 rlvAttachments.push_back(objectp->getLocalID());
7940 }
7941 }
7942
7943 // Only send the message if we actually have something to detach
7944 if (rlvAttachments.size() > 0)
7945 {
7946 gMessageSystem->newMessage("ObjectDetach");
7947 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
7948 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
7949 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
7950
7951 for (std::list<U32>::const_iterator itAttach = rlvAttachments.begin(); itAttach != rlvAttachments.end(); ++itAttach)
7952 {
7766 gMessageSystem->nextBlockFast(_PREHASH_ObjectData); 7953 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
7767 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, objectp->getLocalID()); 7954 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, *itAttach);
7768 } 7955 }
7956
7957 gMessageSystem->sendReliable( gAgent.getRegionHost() );
7769 } 7958 }
7770 gMessageSystem->sendReliable( gAgent.getRegionHost() ); 7959
7960 #ifdef RLV_EXPERIMENTAL_COMPOSITES
7961 if (rlv_handler_t::isEnabled)
7962 {
7963 // If we encountered any composite folders then we need to @detach all of them
7964 for (std::list<LLUUID>::const_iterator itFolder = rlvCompFolders.begin(); itFolder != rlvCompFolders.end(); ++itFolder)
7965 {
7966 std::string strFolder = gRlvHandler.getSharedPath(*itFolder);
7967
7968 // It shouldn't happen but make absolutely sure that we don't issue @detach:=force and reenter this function
7969 if (!strFolder.empty())
7970 {
7971 std::string strCmd = "detach:" + strFolder + "=force";
7972 #ifdef RLV_DEBUG
7973 RLV_INFOS << "\t- detaching composite folder: @" << strCmd << LL_ENDL;
7974 #endif // RLV_DEBUG
7975
7976 // HACK-RLV: executing a command while another command is currently executing isn't the best thing to do, however
7977 // in this specific case it is safe (and still better than making processForceCommand public)
7978 gRlvHandler.processCommand(gRlvHandler.getCurrentObject(), strCmd);
7979 }
7980 }
7981 }
7982 #endif // RLV_EXPERIMENTAL_COMPOSITES
7983// [/RLVa:KB]
7771} 7984}
7772 7985
7773void LLAgent::observeFriends() 7986void LLAgent::observeFriends()