diff --git a/README b/README index 4a048e09c..a441bfedf 100644 --- a/README +++ b/README @@ -18,7 +18,7 @@ as those based upon the OpenSim platform. Singulariy is maintained by a small group of volunteers who can be contacted both, in-world (SingularityViewer group) as well on IRC (#SingularityViewer @ FreeNode). Bug requests and features requests can be submitted through our -Issue Tracket (http://code.google.com/p/singularity-viewer/issues/list or from +Issue Tracker (http://code.google.com/p/singularity-viewer/issues/list or from the viewer menu: Help --> Bug Reporting --> Singularity Issue Tracker...) @@ -33,6 +33,6 @@ As this Readme grows out of date, please refer to History The Singularity viewer was started by Siana Gearz in November 2010 by forking it -of the Ascent Viewer, by Balseraph Software Group, which in turn was based upon -source code released by Linden Lab. +from the Ascent Viewer, by Balseraph Software Group, which in turn was based upon +source code modified from the snowglobe source code released by Linden Lab. diff --git a/indra/llmessage/aihttptimeoutpolicy.cpp b/indra/llmessage/aihttptimeoutpolicy.cpp index 8677a0ac2..354ec4625 100644 --- a/indra/llmessage/aihttptimeoutpolicy.cpp +++ b/indra/llmessage/aihttptimeoutpolicy.cpp @@ -646,6 +646,12 @@ AIHTTPTimeoutPolicyBase transfer_18s(AIHTTPTimeoutPolicyBase::getDebugSettingsCu transactionOp18s ); +// This used to be '30 seconds'. +Transaction transactionOp30s(30); +AIHTTPTimeoutPolicyBase transfer_30s(AIHTTPTimeoutPolicyBase::getDebugSettingsCurlTimeout(), + transactionOp30s + ); + // This used to be '300 seconds'. We derive this from the hardcoded result so users can't mess with it. Transaction transactionOp300s(300); AIHTTPTimeoutPolicyBase transfer_300s(HTTPTimeoutPolicy_default, @@ -839,6 +845,7 @@ P(estateChangeInfoResponder); P(eventPollResponder); P(fetchInventoryResponder); P(fnPtrResponder); +P2(groupMemberDataResponder, transfer_300s); P2(groupProposalBallotResponder, transfer_300s); P(homeLocationResponder); P(HTTPGetResponder); @@ -851,6 +858,7 @@ P(lcl_responder); P(MPImportGetResponder); P(MPImportPostResponder); P(mapLayerResponder); +P2(maturityPreferences, transfer_30s); P(mediaTypeResponder); P(meshDecompositionResponder); P(meshHeaderResponder); diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp index cd71efea9..48b6e4f63 100644 --- a/indra/llmessage/llavatarnamecache.cpp +++ b/indra/llmessage/llavatarnamecache.cpp @@ -24,12 +24,12 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ - #include "linden_common.h" #include "llavatarnamecache.h" #include "llcachename.h" // we wrap this system +#include "llcontrol.h" // For LLCachedControl #include "llframetimer.h" #include "llhttpclient.h" #include "llsd.h" @@ -624,7 +624,6 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) // ...only do immediate lookups when cache is running if (useDisplayNames()) { - // ...use display names cache std::map::iterator it = sCache.find(agent_id); if (it != sCache.end()) @@ -669,6 +668,29 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name) return false; } +// Return true when name has been set to Phoenix Name System Name, if not return false. +bool LLAvatarNameCache::getPNSName(const LLUUID& agent_id, std::string& name) +{ + LLAvatarName avatar_name; + if (get(agent_id, &avatar_name)) + getPNSName(avatar_name, name); + else return false; + return true; +} + +// get() with callback compatible version of getPNSName +void LLAvatarNameCache::getPNSName(const LLAvatarName& avatar_name, std::string& name) +{ + static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); + switch (phoenix_name_system) + { + case 0 : name = avatar_name.getLegacyName(); break; + case 1 : name = avatar_name.getCompleteName(); break; + case 2 : name = avatar_name.mDisplayName; break; + default : name = avatar_name.getLegacyName(); break; + } +} + void LLAvatarNameCache::fireSignal(const LLUUID& agent_id, const callback_slot_t& slot, const LLAvatarName& av_name) diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h index 18f192c65..99e3fba57 100644 --- a/indra/llmessage/llavatarnamecache.h +++ b/indra/llmessage/llavatarnamecache.h @@ -65,6 +65,12 @@ namespace LLAvatarNameCache // If name is in cache, returns true and fills in provided LLAvatarName // otherwise returns false bool get(const LLUUID& agent_id, LLAvatarName *av_name); + // If get() succeeds, returns true and fills in name string + // via void function below, otherwise returns false + bool getPNSName(const LLUUID& agent_id, std::string& name); + // Perform a filling of name string according to Phoenix Name System, + // when we have an LLAvatarName already. + void getPNSName(const LLAvatarName& avatar_name, std::string& name); // Callback types for get() below typedef boost::signals2::signal< diff --git a/indra/llrender/llpostprocess.cpp b/indra/llrender/llpostprocess.cpp index c1415e3f6..c533701b0 100644 --- a/indra/llrender/llpostprocess.cpp +++ b/indra/llrender/llpostprocess.cpp @@ -49,12 +49,63 @@ extern LLGLSLShader gPostNightVisionProgram; extern LLGLSLShader gPostGaussianBlurProgram; extern LLGLSLShader gPostPosterizeProgram; extern LLGLSLShader gPostMotionBlurProgram; +extern LLGLSLShader gPostVignetteProgram; static const unsigned int NOISE_SIZE = 512; static const char * const XML_FILENAME = "postprocesseffects.xml"; -template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue() +class LLPostProcessShader : public IPostProcessShader, public LLRefCount +{ +public: + LLPostProcessShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) : + mShader(shader), mEnabled(enable_name,enabled) + { + addSetting(mEnabled); + } + /*virtual*/ bool isEnabled() const {return mShader.mProgramObject && mEnabled;} + /*virtual*/ void bindShader() {mShader.bind();} + /*virtual*/ void unbindShader() {mShader.unbind();} + /*virtual*/ LLGLSLShader& getShader() {return mShader;} + + /*virtual*/ LLSD getDefaults(); //See IPostProcessShader::getDefaults + /*virtual*/ void loadSettings(const LLSD& settings); //See IPostProcessShader::loadSettings + /*virtual*/ void addSetting(IShaderSettingBase& setting) { mSettings.push_back(&setting); } +protected: + template + struct LLShaderSetting : public IShaderSettingBase + { + LLShaderSetting(const std::string& name, T def) : + mValue(def), mDefault(def), mSettingName(name) {} + operator T() const { return mValue; } + T get() const { return mValue; } + /*virtual*/ const std::string& getName() const { return mSettingName; } //See LLShaderSettingBase::getName + /*virtual*/ LLSD getDefaultValue() const { return mDefault; } //See LLShaderSettingBase::getDefaultValue + /*virtual*/ void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue + private: + const std::string mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base' + T mValue; //The member variable mentioned above. + T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml + }; +private: + std::vector mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor. + LLGLSLShader& mShader; + LLShaderSetting mEnabled; +}; + +//helpers +class LLPostProcessSinglePassColorShader : public LLPostProcessShader +{ +public: + LLPostProcessSinglePassColorShader(const std::string& enable_name, LLGLSLShader& shader, bool enabled = false) : + LLPostProcessShader(enable_name, shader, enabled) {} + /*virtual*/ S32 getColorChannel() const {return 0;} + /*virtual*/ S32 getDepthChannel() const {return -1;} + /*virtual*/ bool draw(U32 pass) {return pass == 1;} + /*virtual*/ void postDraw() {} +}; + +template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue() const { return mDefault.getValue(); } @@ -66,223 +117,181 @@ template<> void LLPostProcessShader::LLShaderSetting::setValue(const LLSD LLPostProcessShader::getDefaults() { LLSD defaults; - for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) + for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) { - defaults[(*it)->mSettingName]=(*it)->getDefaultValue(); + defaults[(*it)->getName()]=(*it)->getDefaultValue(); } return defaults; } void LLPostProcessShader::loadSettings(const LLSD& settings) { - for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) + for(std::vector::iterator it=mSettings.begin();it!=mSettings.end();++it) { - LLSD value = settings[(*it)->mSettingName]; + LLSD value = settings[(*it)->getName()]; (*it)->setValue(value); } } -class LLColorFilterShader : public LLPostProcessShader +class LLColorFilterShader : public LLPostProcessSinglePassColorShader { private: - LLShaderSetting mEnabled; LLShaderSetting mGamma, mBrightness, mContrast, mSaturation; LLShaderSetting mContrastBase; public: - LLColorFilterShader() : - mEnabled("enable_color_filter",false), + LLColorFilterShader() : + LLPostProcessSinglePassColorShader("enable_color_filter",gPostColorFilterProgram), mGamma("gamma",1.f), mBrightness("brightness",1.f), mContrast("contrast",1.f), mSaturation("saturation",1.f), mContrastBase("contrast_base",LLVector4(1.f,1.f,1.f,0.5f)) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mGamma); - mSettings.push_back(&mBrightness); - mSettings.push_back(&mContrast); - mSettings.push_back(&mSaturation); - mSettings.push_back(&mContrastBase); + addSetting(mGamma); + addSetting(mBrightness); + addSetting(mContrast); + addSetting(mSaturation); + addSetting(mContrastBase); } - bool isEnabled() { return mEnabled && gPostColorFilterProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - - QuadType bind() + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; - /// CALCULATING LUMINANCE (Using NTSC lum weights) /// http://en.wikipedia.org/wiki/Luma_%28video%29 static const float LUMINANCE_R = 0.299f; static const float LUMINANCE_G = 0.587f; static const float LUMINANCE_B = 0.114f; - gPostColorFilterProgram.bind(); + getShader().uniform1f("gamma", mGamma); + getShader().uniform1f("brightness", mBrightness); + getShader().uniform1f("contrast", mContrast); + float baseI = (mContrastBase.get()[VX] + mContrastBase.get()[VY] + mContrastBase.get()[VZ]) / 3.0f; + baseI = mContrastBase.get()[VW] / llmax(baseI,0.001f); + float baseR = mContrastBase.get()[VX] * baseI; + float baseG = mContrastBase.get()[VY] * baseI; + float baseB = mContrastBase.get()[VZ] * baseI; + getShader().uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV); + getShader().uniform1f("saturation", mSaturation); - gPostColorFilterProgram.uniform1f("gamma", mGamma); - gPostColorFilterProgram.uniform1f("brightness", mBrightness); - gPostColorFilterProgram.uniform1f("contrast", mContrast); - float baseI = (mContrastBase.mValue[VX] + mContrastBase.mValue[VY] + mContrastBase.mValue[VZ]) / 3.0f; - baseI = mContrastBase.mValue[VW] / ((baseI < 0.001f) ? 0.001f : baseI); - float baseR = mContrastBase.mValue[VX] * baseI; - float baseG = mContrastBase.mValue[VY] * baseI; - float baseB = mContrastBase.mValue[VZ] * baseI; - gPostColorFilterProgram.uniform3fv("contrastBase", 1, LLVector3(baseR, baseG, baseB).mV); - gPostColorFilterProgram.uniform1f("saturation", mSaturation); - gPostColorFilterProgram.uniform3fv("lumWeights", 1, LLVector3(LUMINANCE_R, LUMINANCE_G, LUMINANCE_B).mV); return QUAD_NORMAL; } - bool draw(U32 pass) {return pass == 1;} - void unbind() - { - gPostColorFilterProgram.unbind(); - } }; -class LLNightVisionShader : public LLPostProcessShader +class LLNightVisionShader : public LLPostProcessSinglePassColorShader { private: - LLShaderSetting mEnabled; LLShaderSetting mBrightnessMult, mNoiseStrength; public: LLNightVisionShader() : - mEnabled("enable_night_vision",false), + LLPostProcessSinglePassColorShader("enable_night_vision",gPostNightVisionProgram), mBrightnessMult("brightness_multiplier",3.f), mNoiseStrength("noise_strength",.4f) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mBrightnessMult); - mSettings.push_back(&mNoiseStrength); + addSetting(mBrightnessMult); + addSetting(mNoiseStrength); } - bool isEnabled() { return mEnabled && gPostNightVisionProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; - - gPostNightVisionProgram.bind(); - LLPostProcess::getInstance()->bindNoise(1); - - gPostNightVisionProgram.uniform1f("brightMult", mBrightnessMult); - gPostNightVisionProgram.uniform1f("noiseStrength", mNoiseStrength); - + + getShader().uniform1f("brightMult", mBrightnessMult); + getShader().uniform1f("noiseStrength", mNoiseStrength); + return QUAD_NOISE; - } - bool draw(U32 pass) {return pass == 1;} - void unbind() +}; + +class LLPosterizeShader : public LLPostProcessSinglePassColorShader +{ +private: + LLShaderSetting mNumLayers; +public: + LLPosterizeShader() : LLPostProcessSinglePassColorShader("enable_posterize",gPostPosterizeProgram), + mNumLayers("posterize_layers",2) { - gPostNightVisionProgram.unbind(); + addSetting(mNumLayers); + } + /*virtual*/ QuadType preDraw() + { + getShader().uniform1i("layerCount", mNumLayers); + return QUAD_NORMAL; + } +}; + +class LLVignetteShader : public LLPostProcessSinglePassColorShader +{ +private: + LLShaderSetting mStrength, mRadius, mDarkness, mDesaturation, mChromaticAberration; +public: + LLVignetteShader() : LLPostProcessSinglePassColorShader("enable_vignette",gPostVignetteProgram), + mStrength("vignette_strength",.85f), + mRadius("vignette_radius",.7f), + mDarkness("vignette_darkness",1.f), + mDesaturation("vignette_desaturation",1.5f), + mChromaticAberration("vignette_chromatic_aberration",.05f) + { + addSetting(mStrength); + addSetting(mRadius); + addSetting(mDarkness); + addSetting(mDesaturation); + addSetting(mChromaticAberration); + } + /*virtual*/ QuadType preDraw() + { + LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); + getShader().uniform1f("vignette_strength", mStrength); + getShader().uniform1f("vignette_radius", mRadius); + getShader().uniform1f("vignette_darkness", mDarkness); + getShader().uniform1f("vignette_desaturation", mDesaturation); + getShader().uniform1f("vignette_chromatic_aberration", mChromaticAberration); + getShader().uniform2fv("screen_res", 1, screen_rect.mV); + return QUAD_NORMAL; } }; class LLGaussBlurShader : public LLPostProcessShader { private: - LLShaderSetting mEnabled; LLShaderSetting mNumPasses; GLint mPassLoc; public: - LLGaussBlurShader() : - mEnabled("enable_gauss_blur",false), + LLGaussBlurShader() : LLPostProcessShader("enable_gauss_blur",gPostGaussianBlurProgram), mNumPasses("gauss_blur_passes",2), mPassLoc(0) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mNumPasses); + addSetting(mNumPasses); } - bool isEnabled() { return mEnabled && mNumPasses && gPostGaussianBlurProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() + /*virtual*/ bool isEnabled() const { return LLPostProcessShader::isEnabled() && mNumPasses.get(); } + /*virtual*/ S32 getColorChannel() const { return 0; } + /*virtual*/ S32 getDepthChannel() const { return -1; } + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - return QUAD_NONE; - - gPostGaussianBlurProgram.bind(); - - mPassLoc = gPostGaussianBlurProgram.getUniformLocation("horizontalPass"); - + mPassLoc = getShader().getUniformLocation("horizontalPass"); return QUAD_NORMAL; } - bool draw(U32 pass) + /*virtual*/ bool draw(U32 pass) { if((S32)pass > mNumPasses*2) return false; glUniform1iARB(mPassLoc, (pass-1) % 2); return true; } - void unbind() - { - gPostGaussianBlurProgram.unbind(); - } -}; - -class LLPosterizeShader : public LLPostProcessShader -{ -private: - LLShaderSetting mEnabled; - LLShaderSetting mNumLayers; -public: - LLPosterizeShader() : - mEnabled("enable_posterize",false), - mNumLayers("posterize_layers",2) - { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mNumLayers); - } - bool isEnabled() { return mEnabled && gPostPosterizeProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return -1; } - QuadType bind() - { - if(!isEnabled()) - return QUAD_NONE; - - gPostPosterizeProgram.bind(); - - gPostPosterizeProgram.uniform1i("layerCount", mNumLayers); - - return QUAD_NORMAL; - } - bool draw(U32 pass) - { - return pass == 1; - } - void unbind() - { - gPostPosterizeProgram.unbind(); - } + /*virtual*/ void postDraw() {} }; class LLMotionShader : public LLPostProcessShader { private: - LLShaderSetting mEnabled; LLShaderSetting mStrength; public: - LLMotionShader() : - mEnabled("enable_motionblur",false), - mStrength("blur_strength",false) + LLMotionShader() : LLPostProcessShader("enable_motionblur",gPostMotionBlurProgram), + mStrength("blur_strength",1) { - mSettings.push_back(&mEnabled); - mSettings.push_back(&mStrength); + addSetting(mStrength); } - bool isEnabled() { return mEnabled && gPostMotionBlurProgram.mProgramObject; } - S32 getColorChannel() { return 0; } - S32 getDepthChannel() { return 1; } - QuadType bind() + /*virtual*/ S32 getColorChannel() const { return 0; } + /*virtual*/ S32 getDepthChannel() const { return 1; } + /*virtual*/ QuadType preDraw() { - if(!isEnabled()) - { - return QUAD_NONE; - } - glh::matrix4f inv_proj(gGLModelView); inv_proj.mult_left(gGLProjection); inv_proj = inv_proj.inverse(); @@ -291,22 +300,18 @@ public: LLVector2 screen_rect = LLPostProcess::getInstance()->getDimensions(); - gPostMotionBlurProgram.bind(); - gPostMotionBlurProgram.uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m); - gPostMotionBlurProgram.uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m); - gPostMotionBlurProgram.uniform2fv("screen_res", 1, screen_rect.mV); - gPostMotionBlurProgram.uniform1i("blur_strength", mStrength); + getShader().uniformMatrix4fv("prev_proj", 1, GL_FALSE, prev_proj.m); + getShader().uniformMatrix4fv("inv_proj", 1, GL_FALSE, inv_proj.m); + getShader().uniform2fv("screen_res", 1, screen_rect.mV); + getShader().uniform1i("blur_strength", mStrength); return QUAD_NORMAL; } - bool draw(U32 pass) + /*virtual*/ bool draw(U32 pass) { return pass == 1; } - void unbind() - { - gPostMotionBlurProgram.unbind(); - } + /*virtual*/ void postDraw() {} }; LLPostProcess::LLPostProcess(void) : @@ -320,12 +325,12 @@ LLPostProcess::LLPostProcess(void) : mAllEffectInfo(LLSD::emptyMap()) { mShaders.push_back(new LLMotionShader()); + mShaders.push_back(new LLVignetteShader()); mShaders.push_back(new LLColorFilterShader()); mShaders.push_back(new LLNightVisionShader()); mShaders.push_back(new LLGaussBlurShader()); mShaders.push_back(new LLPosterizeShader()); - /* Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender.*/ std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; @@ -547,20 +552,19 @@ void LLPostProcess::doEffects(void) void LLPostProcess::applyShaders(void) { - QuadType quad; bool primary_rendertarget = 1; for(std::list >::iterator it=mShaders.begin();it!=mShaders.end();++it) { - if((quad = (*it)->bind()) != QUAD_NONE) + if((*it)->isEnabled()) { S32 color_channel = (*it)->getColorChannel(); S32 depth_channel = (*it)->getDepthChannel(); - if(depth_channel >= 0) gGL.getTexUnit(depth_channel)->bindManual(LLTexUnit::TT_RECT_TEXTURE, mDepthTexture); - U32 pass = 1; + (*it)->bindShader(); + QuadType quad = (*it)->preDraw(); while((*it)->draw(pass++)) { mRenderTarget[!primary_rendertarget].bindTarget(); @@ -573,7 +577,8 @@ void LLPostProcess::applyShaders(void) if(mRenderTarget[0].getFBO()) primary_rendertarget = !primary_rendertarget; } - (*it)->unbind(); + (*it)->postDraw(); + (*it)->unbindShader(); } } //Only need to copy to framebuffer if FBOs are supported, else we've already been drawing to the framebuffer to begin with. diff --git a/indra/llrender/llpostprocess.h b/indra/llrender/llpostprocess.h index 9ecd9e293..6c3da675e 100644 --- a/indra/llrender/llpostprocess.h +++ b/indra/llrender/llpostprocess.h @@ -38,57 +38,48 @@ #include "llrendertarget.h" class LLSD; +class LLGLSLShader; typedef enum _QuadType { - QUAD_NONE, QUAD_NORMAL, QUAD_NOISE } QuadType; //LLPostProcessShader is an attempt to encapsulate the shaders a little better. -class LLPostProcessShader : public LLRefCount //Abstract. PostProcess shaders derive off of this common base. +class IPostProcessShader //Abstract. PostProcess shaders derive off of this common base. { protected: //LLShaderSetting is used to associate key names to member variables to avoid LLSD lookups when drawing. //It also facilitates automating the assigning of defaults to, as well as parsing from, the effects LLSD list. //This replaces the entire old PostProcessTweaks structure. More will be done in the future to move into a more //xml-driven configuration. - struct LLShaderSettingBase + struct IShaderSettingBase { - LLShaderSettingBase(const char* name) : mSettingName(name) {} - const char* mSettingName; //LLSD key names as found in postprocesseffects.xml. eg 'contrast_base' - virtual LLSD getDefaultValue() = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml + virtual ~IShaderSettingBase() {} //virtual dtor. + virtual const std::string& getName() const = 0; //Returns the name of this setting + virtual LLSD getDefaultValue() const = 0; //Converts the member variable as an LLSD. Used to set defaults absent in postprocesseffects.xml virtual void setValue(const LLSD& value) = 0; //Connects the LLSD element to the member variable. Used when loading effects (such as default) }; - template - struct LLShaderSetting : public LLShaderSettingBase - { - LLShaderSetting(const char* setting_name, T def) : LLShaderSettingBase(setting_name), mValue(def), mDefault(def) {} - T mValue; //The member variable mentioned above. - T mDefault; //Set via ctor. Value is inserted into the defaults LLSD list if absent from postprocesseffects.xml - LLSD getDefaultValue() { return mDefault; } //See LLShaderSettingBase::getDefaultValue - void setValue(const LLSD& value) { mValue = value; } //See LLShaderSettingBase::setValue - operator T() { return mValue; } //Typecast operator overload so this object can be handled as if it was whatever T represents. - }; - std::vector mSettings; //Contains a list of all the 'settings' this shader uses. Manually add via push_back in ctor. public: - virtual ~LLPostProcessShader() {}; - virtual bool isEnabled() = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped. - virtual S32 getColorChannel() = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. - virtual S32 getDepthChannel() = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. - virtual QuadType bind() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn. + virtual ~IPostProcessShader() {} //virtual dtor. + virtual bool isEnabled() const = 0; //Returning false avoids bind/draw/unbind calls. If no shaders are enabled, framebuffer copying is skipped. + virtual S32 getColorChannel() const = 0; //If color buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. + virtual S32 getDepthChannel() const = 0; //If depth buffer is used in this shader returns > -1 to cue LLPostProcess on copying it from the framebuffer. + virtual void bindShader() = 0; + virtual void unbindShader() = 0; + virtual LLGLSLShader& getShader() = 0; + + virtual QuadType preDraw() = 0; //Bind shader and textures, set up attribs. Returns the 'type' of quad to be drawn. virtual bool draw(U32 pass) = 0; //returning false means finished. Used to update per-pass attributes and such. LLPostProcess will call //drawOrthoQuad when this returns true, increment pass, then call this again, and keep repeating this until false is returned. - virtual void unbind() = 0; //Unbind shader and textures. + virtual void postDraw() = 0; //Done drawing.. - LLSD getDefaults(); //Returns a full LLSD kvp list filled with default values. - void loadSettings(const LLSD& settings); //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue()) + virtual LLSD getDefaults() = 0; //Returns a full LLSD kvp list filled with default values. + virtual void loadSettings(const LLSD& settings) = 0; //Parses the effects LLSD list and sets the member variables linked to them (via LLShaderSetting::setValue()) + virtual void addSetting(IShaderSettingBase& setting) = 0; }; -//LLVector4 does not implicitly convert to and from LLSD, so template specilizations are necessary. -template<> LLSD LLPostProcessShader::LLShaderSetting::getDefaultValue(); -template<> void LLPostProcessShader::LLShaderSetting::setValue(const LLSD& value); - +class LLPostProcessShader; class LLPostProcess : public LLSingleton { private: diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 385f2e847..65a7fda5e 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -25,6 +25,7 @@ */ #include "linden_common.h" +#include //First, because glh_linear #defines equivalent.. which boost uses internally #include "llshadermgr.h" @@ -53,6 +54,17 @@ LLShaderMgr * LLShaderMgr::sInstance = NULL; LLShaderMgr::LLShaderMgr() { + { + const std::string dumpdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"shader_dump")+gDirUtilp->getDirDelimiter(); + try + { + boost::filesystem::remove_all(dumpdir); + } + catch(const boost::filesystem::filesystem_error& e) + { + llinfos << "boost::filesystem::remove_all(\""+dumpdir+"\") failed: '" + e.code().message() + "'" << llendl; + } + } } diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp index a0a9b36b9..bd99e6c73 100644 --- a/indra/llui/llresizebar.cpp +++ b/indra/llui/llresizebar.cpp @@ -54,6 +54,7 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const mAllowDoubleClickSnapping(TRUE), mResizingView(resizing_view) { + setFollowsNone(); // set up some generically good follow code. switch( side ) { @@ -87,6 +88,8 @@ LLResizeBar::LLResizeBar( const std::string& name, LLView* resizing_view, const BOOL LLResizeBar::handleMouseDown(S32 x, S32 y, MASK mask) { + if (!canResize()) return FALSE; + // Route future Mouse messages here preemptively. (Release on mouse up.) // No handler needed for focus lost since this clas has no state that depends on it. gFocusMgr.setMouseCapture( this ); @@ -240,7 +243,7 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask) handled = TRUE; } - if( handled ) + if( handled && canResize() ) { switch( mSide ) { diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h index b9fc40593..14bdd8d16 100644 --- a/indra/llui/llresizebar.h +++ b/indra/llui/llresizebar.h @@ -52,6 +52,7 @@ public: void setResizeLimits( S32 min_size, S32 max_size ) { mMinSize = min_size; mMaxSize = max_size; } void setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; } void setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; } + bool canResize() { return getEnabled() && mMaxSize > mMinSize; } private: S32 mDragLastScreenX; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 11d6433d0..f676eb7fe 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -1093,6 +1093,15 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r addColumn(new_column); } + S32 num_cols = item->getNumColumns(); + S32 i = 0; + for (LLScrollListCell* cell = item->getColumn(i); i < num_cols; cell = item->getColumn(++i)) + { + if (i >= (S32)mColumnsIndexed.size()) break; + + cell->setWidth(mColumnsIndexed[i]->getWidth()); + } + updateLineHeightInsert(item); updateLayout(); @@ -3898,7 +3907,11 @@ LLScrollColumnHeader::~LLScrollColumnHeader() void LLScrollColumnHeader::draw() { - BOOL draw_arrow = !mColumn->mLabel.empty() && mColumn->mParentCtrl->isSorted() && mColumn->mParentCtrl->getSortColumnName() == mColumn->mSortingColumn; + std::string sort_column = mColumn->mParentCtrl->getSortColumnName(); + BOOL draw_arrow = !mColumn->mLabel.empty() + && mColumn->mParentCtrl->isSorted() + // check for indirect sorting column as well as column's sorting name + && (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName); BOOL is_ascending = mColumn->mParentCtrl->getSortAscending(); mButton->setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent); @@ -4014,6 +4027,7 @@ BOOL LLScrollColumnHeader::handleDoubleClick(S32 x, S32 y, MASK mask) if (canResize() && mResizeBar->getRect().pointInRect(x, y)) { // reshape column to max content width + mColumn->mParentCtrl->calcMaxContentWidth(); LLRect column_rect = getRect(); column_rect.mRight = column_rect.mLeft + mColumn->mMaxContentWidth; setShape(column_rect,true); @@ -4308,6 +4322,7 @@ void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user) // tell scroll list to layout columns again // do immediate update to get proper feedback to resize handle // which needs to know how far the resize actually went + mColumn->mParentCtrl->dirtyColumns(); //Must flag as dirty, else updateColumns will probably be a noop. mColumn->mParentCtrl->updateColumns(); } } diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 9ea4d82b8..30a8aba11 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -642,6 +642,18 @@ public: // manually call this whenever editing list items in place to flag need for resorting void setNeedsSort(bool val = true) { mSorted = !val; } + void setNeedsSortColumn(S32 col) + { + if(!isSorted())return; + for(std::vector >::iterator it=mSortColumns.begin();it!=mSortColumns.end();++it) + { + if((*it).first == col) + { + setNeedsSort(); + break; + } + } + } void dirtyColumns(); // some operation has potentially affected column layout or ordering boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 0a988c7a7..69841a042 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -37,11 +37,13 @@ #include "llview.h" #include "llrect.h" #include "llsd.h" +#include +#include #include "llviewmodel.h" // *TODO move dependency to .cpp file class LLUICtrl -: public LLView +: public LLView, public boost::signals2::trackable { public: typedef boost::function commit_callback_t; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 511641635..049933443 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -313,6 +313,7 @@ set(viewer_SOURCE_FILES llmediaremotectrl.cpp llmemoryview.cpp llmenucommands.cpp + llmenuoptionpathfindingrebakenavmesh.cpp llmeshrepository.cpp llmimetypes.cpp llmorphview.cpp @@ -367,7 +368,6 @@ set(viewer_SOURCE_FILES llpanelnetwork.cpp llpanelobject.cpp llpanelobjectinventory.cpp - llpanelpathfindingrebakenavmesh.cpp llpanelpermissions.cpp llpanelpick.cpp llpanelplace.cpp @@ -820,6 +820,7 @@ set(viewer_HEADER_FILES llmediactrl.h llmediaremotectrl.h llmemoryview.h + llmenuoptionpathfindingrebakenavmesh.h llmenucommands.h llmeshrepository.h llmimetypes.h @@ -875,7 +876,6 @@ set(viewer_HEADER_FILES llpanelnetwork.h llpanelobject.h llpanelobjectinventory.h - llpanelpathfindingrebakenavmesh.h llpanelpermissions.h llpanelpick.h llpanelplace.h diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini index dd50567cd..0cc3d6693 100644 --- a/indra/newview/app_settings/keywords.ini +++ b/indra/newview/app_settings/keywords.ini @@ -701,7 +701,23 @@ CHARACTER_MAX_TURN_RADIUS TODO: add documentation # --- OpenSim and Aurora-Sim constants Below --- # OpenSim Constants (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\LSL_Constants.cs) # Constants for cmWindlight (\OpenSim\Region\ScriptEngine\Shared\Api\Runtime\CM_Constants.cs) -CHANGED_ANIMATION OpenSim change event animation change detection. +CHANGED_ANIMATION OpenSim change event animation change detection. +CAMERA_FOCUS_OFFSET_X OpenSim enhancement for llSetCameraParams(), adjusts the camera focus x position relative to the target. (float) +CAMERA_FOCUS_OFFSET_Y OpenSim enhancement for llSetCameraParams(), adjusts the camera focus y position relative to the target. (float) +CAMERA_FOCUS_OFFSET_Z OpenSim enhancement for llSetCameraParams(), adjusts the camera focus z position relative to the target. (float) +CAMERA_POSITION_X OpenSim enhancement for llSetCameraParams(), sets camera x position in region coordinates. (float) +CAMERA_POSITION_Y OpenSim enhancement for llSetCameraParams(), sets camera y position in region coordinates. (float) +CAMERA_POSITION_Z OpenSim enhancement for llSetCameraParams(), sets camera z position in region coordinates. (float) +CAMERA_FOCUS_X OpenSim enhancement for llSetCameraParams(), sets camera x focus (target position) in region coordinates. (float) +CAMERA_FOCUS_Y OpenSim enhancement for llSetCameraParams(), sets camera y focus (target position) in region coordinates. (float) +CAMERA_FOCUS_Z OpenSim enhancement for llSetCameraParams(), sets camera z focus (target position) in region coordinates. (float) +OS_LISTEN_REGEX_NAME Value 0x1, process name parameter as regex +OS_LISTEN_REGEX_MESSAGE Value 0x2, process name parameter as regex +OS_ATTACH_MSG_ALL Used with osMessageAttachements +OS_ATTACH_MSG_INVERT_POINTS Used with osMessageAttachements +OS_ATTACH_MSG_OBJECT_CREATOR Used with osMessageAttachements +OS_ATTACH_MSG_SCRIPT_CREATOR Used with osMessageAttachements +PARCEL_DETAILS_CLAIMDATE Used with osSetParcelDetails # osGetRegionStats STATS_TIME_DILATION returned value from osGetRegionStats(), 1st of 21 items in returned list. STATS_SIM_FPS returned value from osGetRegionStats(), 2nd of 21 items in returned list. @@ -725,14 +741,15 @@ STATS_PENDING_UPLOADS returned value from osGetRegionStats(), 19th of 21 items STATS_ACTIVE_SCRIPTS returned value from osGetRegionStats(), 20th of 21 items in returned list. STATS_SCRIPT_LPS returned value from osGetRegionStats(), 21st of 21 items in returned list. # OpenSim NPC -OS_NPC_FLY used by osNPC. -OS_NPC_NO_FLY used by osNPC. -OS_NPC_LAND_AT_TARGET used by osNPC. -OS_NPC_SIT_NOW used by osNPC. -OS_NPC_CREATOR_OWNED used by osNPC. -OS_NPC_NOT_OWNED used by osNPC. -OS_NPC_SENSE_AS_AGENT used by osNPC. -OS_NPC_RUNNING used by osNPC. +OS_NPC used by osNPC. Value 0x01000000 +OS_NPC_FLY used by osNPC. Value 0 +OS_NPC_NO_FLY used by osNPC. Value 1 +OS_NPC_LAND_AT_TARGET used by osNPC. Value 2 +OS_NPC_SIT_NOW used by osNPC. Value 0 +OS_NPC_CREATOR_OWNED used by osNPC. Value 0x1 +OS_NPC_NOT_OWNED used by osNPC. Value 0x2 +OS_NPC_SENSE_AS_AGENT used by osNPC. Value 0x4 +OS_NPC_RUNNING used by osNPC. Value 4 # Windlight/Lightshare WL_WATER_COLOR Windlight Water Colour WL_WATER_FOG_DENSITY_EXPONENT Windlight Water Fog Density Exponent @@ -771,7 +788,15 @@ WL_CLOUD_SCROLL_Y Windlight Cloud Scroll Y WL_CLOUD_SCROLL_Y_LOCK Windlight Cloud Scroll Y Lock WL_CLOUD_SCROLL_X_LOCK Windlight Cloud Scroll X Lock WL_DRAW_CLASSIC_CLOUDS Windlight Draw Classic Clouds -# Aurora-Sim Constants (\Aurora\AuroraDotNetEngine\APIs\AA_Constants.cs) --> +# WL Constants added unique to Aurora-Sim +WL_OK Value -1 +WL_ERROR Value -2 +WL_ERROR_NO_SCENE_SET Value -3 +WL_ERROR_SCENE_MUST_BE_STATIC Value -4 +WL_ERROR_SCENE_MUST_NOT_BE_STATIC Value -5 +WL_ERROR_BAD_SETTING Value -6 +WL_ERROR_NO_PRESET_FOUND Value -7 +# Aurora-Sim Constants (\Aurora\AuroraDotNetEngine\APIs\AA_Constants.cs) ENABLE_GRAVITY enable_gravity. GRAVITY_FORCE_X gravity_force_x. GRAVITY_FORCE_Y gravity_force_y. diff --git a/indra/newview/app_settings/lsl_functions_os.xml b/indra/newview/app_settings/lsl_functions_os.xml index 05e1c94f8..1d19505b3 100644 --- a/indra/newview/app_settings/lsl_functions_os.xml +++ b/indra/newview/app_settings/lsl_functions_os.xml @@ -247,6 +247,46 @@ osNpcWhisper + osForceAttachToAvatar + + osForceAttachToAvatarFromInventory + + osForceAttachToOtherAvatarFromInventory + + osNpcTouch + + osNpcTouch + + osIsUUID + + osMin + + osMax + + osMax + + osGetRezzingObject + + osGetHealth + + osSetContentType + + osGetNumberOfAttachments + + osMessageAttachments + + osDropAttachments + + osDropAttachmentsAt + + osForceDropAttachments + + osForceDropAttachmentsAt + + osListenRegex + + osRegexIsMatch + osReturnObject @@ -334,6 +374,24 @@ aaGetIsInfiniteRegion + aaSetCharacterStat + + aaAllRegionInstanceSay + + aaWindlightGetDayCycle + + aaWindlightAddDayCycleFrame + + aaWindlightRemoveDayCycleFrame + + aaWindlightSetScene + + aaWindlightGetScene + + aaWindlightGetSceneIsStatic + + aaWindlightGetSceneDayCycleKeyFrameCount + botGetWaitingTime @@ -370,4 +428,4 @@ botRemoveBotsWithTag - \ No newline at end of file + diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bdbad4b53..b1f80fa95 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -692,11 +692,55 @@ Boolean Value 0 - + + LiruAddNotReplace + + Comment + Add clothing and attachments instead of having them replace the currently worn or attached item at their destination. + Persist + 1 + Type + Boolean + Value + 0 + + LiruContinueFlyingOnUnsit + + Comment + Fly after standing up, if you were flying when you sat down + Persist + 1 + Type + Boolean + Value + 0 + + LiruFlyAfterTeleport + + Comment + Fly after teleports + Persist + 1 + Type + Boolean + Value + 0 + + LiruNoTransactionClutter + + Comment + Use notifytips for transactions instead of notifys, this way they do not collect in the top right of the screen. + Persist + 1 + Type + Boolean + Value + 0 + LiruSensibleARC Comment - Use the old-style way to calculate Avatar Render Cost. + Use the old-style way to calculate Avatar Render Cost. Found in Advanced->Rendering->Info Displays Persist 1 @@ -704,7 +748,7 @@ Found in Advanced->Rendering->Info Displays Boolean Value 1 - + MarketImporterUpdateFreq Comment @@ -865,6 +909,17 @@ This should be as low as possible, but too low may break functionality Value 0 + TurnAroundWhenWalkingBackwards + + Comment + Turn your avatar around to face the camera while walking backwards. + Persist + 1 + Type + Boolean + Value + 1 + EmeraldBoobMass Comment @@ -6274,6 +6329,149 @@ This should be as low as possible, but too low may break functionality 0 + RadarColumnMarkWidth + + Comment + Width for radar's mark column + Persist + 1 + Type + S32 + Value + 12 + + RadarColumnPositionWidth + + Comment + Width for radar's position column + Persist + 1 + Type + S32 + Value + 60 + + RadarColumnAltitudeWidth + + Comment + Width for radar's altitude column + Persist + 1 + Type + S32 + Value + 48 + + RadarColumnActivityWidth + + Comment + Width for radar's activity column + Persist + 1 + Type + S32 + Value + 24 + + RadarColumnAgeWidth + + Comment + Width for radar's age column + Persist + 1 + Type + S32 + Value + 45 + + RadarColumnTimeWidth + + Comment + Width for radar's time column + Persist + 1 + Type + S32 + Value + 52 + + RadarColumnMarkHidden + + Comment + Hide radar's mark column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnPositionHidden + + Comment + Hide radar's position column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnAltitudeHidden + + Comment + Hide radar's altitude column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnActivityHidden + + Comment + Hide radar's activity column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnAgeHidden + + Comment + Hide radar's age column + Persist + 1 + Type + Boolean + Value + 0 + + RadarColumnTimeHidden + + Comment + Hide radar's time column + Persist + 1 + Type + Boolean + Value + 1 + + RadarColumnClientHidden + + Comment + Hide radar's client column + Persist + 1 + Type + Boolean + Value + 0 + RadarKeepOpen Comment @@ -6340,6 +6538,28 @@ This should be as low as possible, but too low may break functionality Value 1 + RadarAlertAge + + Comment + Whether the radar emits chat alerts for avatars younger than AvatarAgeAlertDays appearing. + Persist + 1 + Type + Boolean + Value + 0 + + AvatarAgeAlertDays + + Comment + Age below which avatars will be made known to you + Persist + 1 + Type + U32 + Value + 3 + RadarChatAlerts Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl index 46b34c6d3..4eefdd8b6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl @@ -60,7 +60,7 @@ void main() /// Gamma correct for WL (soft clip effect). frag_data[0] = vec4(scaleSoftClip(color.rgb), 1.0); - frag_data[1] = vec4(0.0,0.0,0.0,0.0); + frag_data[1] = vec4(vary_HazeColor.a,0.0,0.0,0.0); //#define PACK_NORMALS #ifdef PACK_NORMALS frag_data[2] = vec4(0.5,0.5,0.0,0.0); diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 7c02d31d4..f5a0bfec6 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -53,6 +53,13 @@ uniform vec4 glow; uniform vec4 cloud_color; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main() { @@ -151,6 +158,7 @@ void main() // At horizon, blend high altitude sky color towards the darker color below the clouds vary_HazeColor += (additiveColorBelowCloud - vary_HazeColor) * (1. - sqrt(temp1)); + vary_HazeColor.a = pow(clamp(luminance(vary_HazeColor.rgb)-.5,0,1),2); // won't compile on mac without this being set //vary_AtmosAttenuation = vec3(0.0,0.0,0.0); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index 33856994d..066cdd348 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -278,6 +278,13 @@ vec3 unpack(vec2 tc) #endif } +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main() { vec2 tc = vary_fragcoord.xy; @@ -316,17 +323,20 @@ void main() //add environmentmap vec3 env_vec = env_mat * refnormpersp; - col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, - max(spec.a-diffuse.a*2.0, 0.0)); + vec3 env = textureCube(environmentMap, env_vec).rgb; + bloom = (luminance(env) - .45)*.25; + col = mix(col.rgb, env, + max(spec.a-diffuse.a*2.0, 0.0)); } col = atmosLighting(col); col = scaleSoftClip(col); - col = mix(col.rgb, diffuse.rgb, diffuse.a); + col = mix(col, diffuse.rgb, diffuse.a); } else { + bloom = spec.r; col = diffuse.rgb; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl index 71486156f..2e4b416c4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl @@ -29,6 +29,8 @@ out vec4 frag_data[3]; #define frag_data gl_FragData #endif +uniform float custom_alpha; + VARYING vec4 vertex_color; VARYING vec2 vary_texcoord0; @@ -38,7 +40,7 @@ void main() { vec4 col = vertex_color * texture2D(diffuseMap, vary_texcoord0.xy); - frag_data[0] = col; + frag_data[0] = vec4(col.rgb,col.a*custom_alpha); frag_data[1] = vec4(0,0,0,0); //#define PACK_NORMALS #ifdef PACK_NORMALS diff --git a/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl new file mode 100644 index 000000000..ad989e1a0 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/effects/VignetteF.glsl @@ -0,0 +1,54 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +#ifdef DEFINE_GL_FRAGCOLOR +out vec4 frag_color; +#else +#define frag_color gl_FragColor +#endif + +uniform sampler2DRect tex0; +uniform float vignette_strength; //0 - 1 +uniform float vignette_radius; //0 - 8 +uniform float vignette_darkness; //0 - 1 +uniform float vignette_desaturation; //0 - 10 +uniform float vignette_chromatic_aberration; //0 - .1 +uniform vec2 screen_res; + +VARYING vec2 vary_texcoord0; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + vec3 color = texture2DRect(tex0, vary_texcoord0).rgb; + vec2 norm_texcood = (vary_texcoord0/screen_res); + vec2 offset = norm_texcood-vec2(.5); + float vignette = clamp(pow(1 - dot(offset,offset),vignette_radius) + 1-vignette_strength, 0.0, 1.0); + float inv_vignette = 1-vignette; + + //vignette chromatic aberration (g + vec2 shift = screen_res * offset * vignette_chromatic_aberration * inv_vignette; + float g = texture2DRect(tex0,vary_texcoord0-shift).g; + float b = texture2DRect(tex0,vary_texcoord0-2*shift).b; + color.gb = vec2(g,b); + + //vignette 'black' overlay. + color = mix(color * vignette, color, 1-vignette_darkness); + + //vignette desaturation + color = mix(vec3(luminance(color)), color, clamp(1-inv_vignette*vignette_desaturation,0,1)); + + frag_color = vec4(color,1.0); +} diff --git a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl index e03b83113..6acd277bb 100644 --- a/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl +++ b/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl @@ -25,6 +25,13 @@ uniform float gamma; VARYING vec2 vary_texcoord0; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + void main(void) { vec3 color = vec3(texture2DRect(tex0, vary_texcoord0.st)); @@ -39,7 +46,7 @@ void main(void) color = mix(contrastBase, color, contrast); /// Modulate saturation - color = mix(vec3(dot(color, lumWeights)), color, saturation); + color = mix(vec3(luminance(color)), color, saturation); frag_color = vec4(color, 1.0); } diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl index 01eed18de..4c8d1b2d1 100644 --- a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl +++ b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl @@ -30,7 +30,7 @@ uniform int texture_index_in; ATTRIBUTE vec3 position; VARYING vec3 position_out; -VARYING int texture_index_out; +VARYING_FLAT int texture_index_out; void main() { diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 1455be080..d490b5d46 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -79,6 +79,13 @@ vec3 vary_AmblitColor; vec3 vary_AdditiveColor; vec3 vary_AtmosAttenuation; +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + vec4 getPosition_d(vec2 pos_screen, float depth) { vec2 sc = pos_screen.xy*2.0; @@ -290,14 +297,13 @@ void main() float da = max(dot(norm.xyz, sun_dir.xyz), 0.0); vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); vec3 col; float bloom = 0.0; if (diffuse.a < 0.9) { - vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); - vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; float scol = max(scol_ambocc.r, diffuse.a); float ambocc = scol_ambocc.g; @@ -324,7 +330,9 @@ void main() //add environmentmap vec3 env_vec = env_mat * refnormpersp; - col = mix(col.rgb, textureCube(environmentMap, env_vec).rgb, + vec3 env = textureCube(environmentMap, env_vec).rgb; + bloom = (luminance(env) - .45)*.25; + col = mix(col.rgb, env, max(spec.a-diffuse.a*2.0, 0.0)); } @@ -335,6 +343,7 @@ void main() } else { + bloom = spec.r; col = diffuse.rgb; } diff --git a/indra/newview/app_settings/windlight/postprocesseffects.xml b/indra/newview/app_settings/windlight/postprocesseffects.xml index b5b173b40..5a498009c 100644 --- a/indra/newview/app_settings/windlight/postprocesseffects.xml +++ b/indra/newview/app_settings/windlight/postprocesseffects.xml @@ -177,6 +177,8 @@ enable_posterize 0 enable_motionblur + 0 + enable_vignette 0 gauss_blur_passes 2 @@ -194,6 +196,16 @@ 10 blur_strength 10 + vignette_strength + 0.85 + vignette_radius + 0.7 + vignette_darkness + 1.0 + vignette_desaturation + 1.0 + vignette_chromatic_aberration + 0.01 \ No newline at end of file diff --git a/indra/newview/ascentprefschat.cpp b/indra/newview/ascentprefschat.cpp index f937571c3..cb7b9e906 100644 --- a/indra/newview/ascentprefschat.cpp +++ b/indra/newview/ascentprefschat.cpp @@ -390,6 +390,7 @@ void LLPrefsAscentChat::refreshValues() mSoundMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundMulti"); mNewLines = gSavedSettings.getU32("_NACL_AntiSpamNewlines"); mPreloadMulti = gSavedSettings.getU32("_NACL_AntiSpamSoundPreloadMulti"); + mEnableGestureSounds = gSavedSettings.getBOOL("EnableGestureSounds"); //Text Options ------------------------------------------------------------------------ mSpellDisplay = gSavedSettings.getBOOL("SpellDisplay"); @@ -607,6 +608,7 @@ void LLPrefsAscentChat::cancel() gSavedSettings.setU32("_NACL_AntiSpamSoundMulti", mSoundMulti); gSavedSettings.setU32("_NACL_AntiSpamNewlines", mNewLines); gSavedSettings.setU32("_NACL_AntiSpamSoundPreloadMulti", mPreloadMulti); + gSavedSettings.setBOOL("EnableGestureSounds", mEnableGestureSounds); //Text Options ------------------------------------------------------------------------ gSavedSettings.setBOOL("SpellDisplay", mSpellDisplay); diff --git a/indra/newview/ascentprefschat.h b/indra/newview/ascentprefschat.h index 8bbfad0c0..cc335cf3e 100644 --- a/indra/newview/ascentprefschat.h +++ b/indra/newview/ascentprefschat.h @@ -104,6 +104,7 @@ protected: BOOL mSoundMulti; U32 mNewLines; U32 mPreloadMulti; + bool mEnableGestureSounds; //Text Options ------------------------------------------------------------------------ BOOL mSpellDisplay; diff --git a/indra/newview/ascentprefssys.cpp b/indra/newview/ascentprefssys.cpp index f8eac7fec..ba835d7ac 100644 --- a/indra/newview/ascentprefssys.cpp +++ b/indra/newview/ascentprefssys.cpp @@ -267,6 +267,8 @@ void LLPrefsAscentSys::refreshValues() mDoubleClickTeleport = gSavedSettings.getBOOL("DoubleClickTeleport"); mResetCameraAfterTP = gSavedSettings.getBOOL("OptionRotateCamAfterLocalTP"); mOffsetTPByUserHeight = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); + mLiruFlyAfterTeleport = gSavedSettings.getBOOL("LiruFlyAfterTeleport"); + mLiruContinueFlying = gSavedSettings.getBOOL("LiruContinueFlyingOnUnsit"); mPreviewAnimInWorld = gSavedSettings.getBOOL("PreviewAnimInWorld"); mSaveScriptsAsMono = gSavedSettings.getBOOL("SaveInventoryScriptsAsMono"); mAlwaysRezInGroup = gSavedSettings.getBOOL("AscentAlwaysRezInGroup"); @@ -416,6 +418,8 @@ void LLPrefsAscentSys::cancel() gSavedSettings.setBOOL("DoubleClickTeleport", mDoubleClickTeleport); gSavedSettings.setBOOL("OptionRotateCamAfterLocalTP", mResetCameraAfterTP); gSavedSettings.setBOOL("OptionOffsetTPByAgentHeight", mOffsetTPByUserHeight); + gSavedSettings.setBOOL("LiruFlyAfterTeleport", mLiruFlyAfterTeleport); + gSavedSettings.setBOOL("LiruContinueFlyingOnUnsit", mLiruContinueFlying); gSavedSettings.setBOOL("PreviewAnimInWorld", mPreviewAnimInWorld); gSavedSettings.setBOOL("SaveInventoryScriptsAsMono", mSaveScriptsAsMono); gSavedSettings.setBOOL("AscentAlwaysRezInGroup", mAlwaysRezInGroup); diff --git a/indra/newview/ascentprefssys.h b/indra/newview/ascentprefssys.h index 336828999..73765ee39 100644 --- a/indra/newview/ascentprefssys.h +++ b/indra/newview/ascentprefssys.h @@ -58,6 +58,8 @@ protected: BOOL mDoubleClickTeleport; BOOL mResetCameraAfterTP; BOOL mOffsetTPByUserHeight; + bool mLiruFlyAfterTeleport; + bool mLiruContinueFlying; BOOL mPreviewAnimInWorld; BOOL mSaveScriptsAsMono; BOOL mAlwaysRezInGroup; diff --git a/indra/newview/ascentprefsvan.cpp b/indra/newview/ascentprefsvan.cpp index 53f0d5751..5fdc90bed 100644 --- a/indra/newview/ascentprefsvan.cpp +++ b/indra/newview/ascentprefsvan.cpp @@ -178,6 +178,8 @@ void LLPrefsAscentVan::refreshValues() mPlayTPSound = gSavedSettings.getBOOL("OptionPlayTpSound"); mShowLogScreens = !gSavedSettings.getBOOL("AscentDisableLogoutScreens"); mDisableChatAnimation = gSavedSettings.getBOOL("SGDisableChatAnimation"); + mAddNotReplace = gSavedSettings.getBOOL("LiruAddNotReplace"); + mTurnAround = gSavedSettings.getBOOL("TurnAroundWhenWalkingBackwards"); //Tags\Colors ---------------------------------------------------------------------------- mAscentUseTag = gSavedSettings.getBOOL("AscentUseTag"); @@ -252,6 +254,8 @@ void LLPrefsAscentVan::cancel() gSavedSettings.setBOOL("OptionPlayTpSound", mPlayTPSound); gSavedSettings.setBOOL("AscentDisableLogoutScreens", !mShowLogScreens); gSavedSettings.setBOOL("SGDisableChatAnimation", mDisableChatAnimation); + gSavedSettings.setBOOL("LiruAddNotReplace", mAddNotReplace); + gSavedSettings.setBOOL("TurnAroundWhenWalkingBackwards", mTurnAround); //Tags\Colors ---------------------------------------------------------------------------- gSavedSettings.setBOOL("AscentUseTag", mAscentUseTag); diff --git a/indra/newview/ascentprefsvan.h b/indra/newview/ascentprefsvan.h index 115b1c206..ec96b8cac 100644 --- a/indra/newview/ascentprefsvan.h +++ b/indra/newview/ascentprefsvan.h @@ -58,6 +58,8 @@ protected: BOOL mPlayTPSound; BOOL mShowLogScreens; bool mDisableChatAnimation; + bool mAddNotReplace; + bool mTurnAround; //Tags\Colors BOOL mAscentUseTag; std::string mReportClientUUID; diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 38d77b8fc..61b771ea2 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -50,7 +50,6 @@ #include "llmoveview.h" #include "llchatbar.h" #include "llnotificationsutil.h" -#include "llpanelpathfindingrebakenavmesh.h" #include "llparcel.h" #include "llrendersphere.h" #include "llsdmessage.h" @@ -131,6 +130,104 @@ std::string gAuthString; LLUUID gReSitTargetID; LLVector3 gReSitOffset; // +class LLTeleportRequest +{ +public: + enum EStatus + { + kPending, + kStarted, + kFailed, + kRestartPending + }; + + LLTeleportRequest(); + virtual ~LLTeleportRequest(); + + EStatus getStatus() const {return mStatus;}; + void setStatus(EStatus pStatus) {mStatus = pStatus;}; + + virtual bool canRestartTeleport(); + + virtual void startTeleport() = 0; + virtual void restartTeleport(); + +protected: + +private: + EStatus mStatus; +}; + +class LLTeleportRequestViaLandmark : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId); + virtual ~LLTeleportRequestViaLandmark(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLUUID &getLandmarkId() const {return mLandmarkId;}; + +private: + LLUUID mLandmarkId; +}; + +class LLTeleportRequestViaLure : public LLTeleportRequestViaLandmark +{ +public: + LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike); + virtual ~LLTeleportRequestViaLure(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + +protected: + inline BOOL isLureGodLike() const {return mIsLureGodLike;}; + +private: + BOOL mIsLureGodLike; +}; + +class LLTeleportRequestViaLocation : public LLTeleportRequest +{ +public: + LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocation(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + inline const LLVector3d &getPosGlobal() const {return mPosGlobal;}; + +private: + LLVector3d mPosGlobal; +}; + + +class LLTeleportRequestViaLocationLookAt : public LLTeleportRequestViaLocation +{ +public: + LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal); + virtual ~LLTeleportRequestViaLocationLookAt(); + + virtual bool canRestartTeleport(); + + virtual void startTeleport(); + virtual void restartTeleport(); + +protected: + +private: + +}; //-------------------------------------------------------------------- // Statics // @@ -201,6 +298,19 @@ LLAgent::LLAgent() : mbTeleportKeepsLookAt(false), mAgentAccess(new LLAgentAccess(gSavedSettings)), + mGodLevelChangeSignal(), + mCanEditParcel(false), + mTeleportRequest(), + mTeleportFinishedSlot(), + mTeleportFailedSlot(), + mIsMaturityRatingChangingDuringTeleport(false), + mMaturityRatingChange(0U), + mIsDoSendMaturityPreferenceToServer(false), + mMaturityPreferenceRequestId(0U), + mMaturityPreferenceResponseId(0U), + mMaturityPreferenceNumRetries(0U), + mLastKnownRequestMaturity(SIM_ACCESS_MIN), + mLastKnownResponseMaturity(SIM_ACCESS_MIN), mTeleportState( TELEPORT_NONE ), mRegionp(NULL), @@ -277,9 +387,21 @@ void LLAgent::init() gSavedSettings.getControl("PreferredMaturity")->getValidateSignal()->connect(boost::bind(&LLAgent::validateMaturity, this, _2)); gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLAgent::handleMaturity, this, _2)); + mLastKnownResponseMaturity = static_cast(gSavedSettings.getU32("PreferredMaturity")); + mLastKnownRequestMaturity = mLastKnownResponseMaturity; + mIsDoSendMaturityPreferenceToServer = true; LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback)); + if (!mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this)); + } + if (!mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this)); + } + mInitialized = TRUE; } @@ -292,6 +414,14 @@ void LLAgent::cleanup() if(mPendingLure) delete mPendingLure; mPendingLure = NULL; + if (mTeleportFinishedSlot.connected()) + { + mTeleportFinishedSlot.disconnect(); + } + if (mTeleportFailedSlot.connected()) + { + mTeleportFailedSlot.disconnect(); + } } //----------------------------------------------------------------------------- @@ -1866,7 +1996,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(TRUE); gStatusBar->setVisibleForMouselook(true); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(TRUE); LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset); @@ -1960,7 +2089,6 @@ void LLAgent::endAnimationUpdateUI() gMenuBarView->setVisible(FALSE); gStatusBar->setVisibleForMouselook(false); - LLPanelPathfindingRebakeNavmesh::getInstance()->setVisible(FALSE); // clear out camera lag effect gAgentCamera.clearCameraLag(); @@ -2377,38 +2505,271 @@ int LLAgent::convertTextToMaturity(char text) return LLAgentAccess::convertTextToMaturity(text); } -bool LLAgent::sendMaturityPreferenceToServer(int preferredMaturity) +extern AIHTTPTimeoutPolicy maturityPreferences_timeout; +class LLMaturityPreferencesResponder : public LLHTTPClient::ResponderWithResult { - if (!getRegion()) - return false; - - // Update agent access preference on the server - std::string url = getRegion()->getCapability("UpdateAgentInformation"); - if (!url.empty()) - { - // Set new access preference - LLSD access_prefs = LLSD::emptyMap(); - if (preferredMaturity == SIM_ACCESS_PG) - { - access_prefs["max"] = "PG"; - } - else if (preferredMaturity == SIM_ACCESS_MATURE) - { - access_prefs["max"] = "M"; - } - if (preferredMaturity == SIM_ACCESS_ADULT) - { - access_prefs["max"] = "A"; - } +public: + LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity); + virtual ~LLMaturityPreferencesResponder(); - LLSD body = LLSD::emptyMap(); - body["access_prefs"] = access_prefs; - llinfos << "Sending access prefs update to " << (access_prefs["max"].asString()) << " via capability to: " - << url << llendl; - LLHTTPClient::post(url, body, new LLHTTPClient::ResponderIgnore); // Ignore response - return true; + virtual void result(const LLSD &pContent); + virtual void error(U32 pStatus, const std::string& pReason); + + virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return maturityPreferences_timeout; } + +private: + U8 parseMaturityFromServerResponse(const LLSD &pContent); + + LLAgent *mAgent; + U8 mPreferredMaturity; + U8 mPreviousMaturity; +}; + +LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity) : + mAgent(pAgent), + mPreferredMaturity(pPreferredMaturity), + mPreviousMaturity(pPreviousMaturity) +{ +} + +LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder() +{ +} + +void LLMaturityPreferencesResponder::result(const LLSD &pContent) +{ + U8 actualMaturity = parseMaturityFromServerResponse(pContent); + + if (actualMaturity != mPreferredMaturity) + { + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', the server responded with '" + << LLViewerRegion::accessToString(actualMaturity) << "' [value:" << static_cast(actualMaturity) << ", llsd:" + << pContent << "]" << llendl; + } + mAgent->handlePreferredMaturityResult(actualMaturity); +} + +void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason) +{ + llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity) + << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '" + << pReason << "' [status:" << pStatus << "]" << llendl; + mAgent->handlePreferredMaturityError(); +} + +U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) +{ + // stinson 05/24/2012 Pathfinding regions have re-defined the response behavior. In the old server code, + // if you attempted to change the preferred maturity to the same value, the response content would be an + // undefined LLSD block. In the new server code with pathfinding, the response content should always be + // defined. Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged + // into server trunk and fully deployed. + U8 maturity = SIM_ACCESS_MIN; + if (pContent.isUndefined()) + { + maturity = mPreferredMaturity; + } + else + { + llassert(!pContent.isUndefined()); + llassert(pContent.isMap()); + + if (!pContent.isUndefined() && pContent.isMap()) + { + // stinson 05/24/2012 Pathfinding regions have re-defined the response syntax. The if statement catches + // the new syntax, and the else statement catches the old syntax. After pathfinding is merged into + // server trunk and fully deployed, we can remove the else statement. + if (pContent.has("access_prefs")) + { + llassert(pContent.has("access_prefs")); + llassert(pContent.get("access_prefs").isMap()); + llassert(pContent.get("access_prefs").has("max")); + llassert(pContent.get("access_prefs").get("max").isString()); + if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") && + pContent.get("access_prefs").get("max").isString()) + { + LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString(); + LLStringUtil::trim(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); + } + } + else if (pContent.has("max")) + { + llassert(pContent.get("max").isString()); + if (pContent.get("max").isString()) + { + LLSD::String actualPreference = pContent.get("max").asString(); + LLStringUtil::trim(actualPreference); + maturity = LLViewerRegion::shortStringToAccess(actualPreference); + } + } + } + } + + return maturity; +} + +void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity) +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Update the last known server maturity response + mLastKnownResponseMaturity = pServerMaturity; + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) + { + // If we received a response that matches the last known request, then we are good + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) + { + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturitySuccess(); + llassert(static_cast(gSavedSettings.getU32("PreferredMaturity")) == mLastKnownResponseMaturity); + } + // Else, the viewer is out of sync with the server, so let's try to re-sync with the + // server by re-sending our last known request. Cap the re-tries at 3 just to be safe. + else if (++mMaturityPreferenceNumRetries <= 3) + { + llinfos << "Retrying attempt #" << mMaturityPreferenceNumRetries << " to set viewer preferred maturity to '" + << LLViewerRegion::accessToString(mLastKnownRequestMaturity) << "'" << llendl; + sendMaturityPreferenceToServer(mLastKnownRequestMaturity); + } + // Else, the viewer is style out of sync with the server after 3 retries, so inform the user + else + { + mMaturityPreferenceNumRetries = 0; + reportPreferredMaturityError(); + } + } +} + +void LLAgent::handlePreferredMaturityError() +{ + // Update the number of responses received + ++mMaturityPreferenceResponseId; + llassert(mMaturityPreferenceResponseId <= mMaturityPreferenceRequestId); + + // Ignore all responses if we know there are more unanswered requests that are expected + if (mMaturityPreferenceResponseId == mMaturityPreferenceRequestId) + { + mMaturityPreferenceNumRetries = 0; + + // If we received a response that matches the last known request, then we are synced with + // the server, but not quite sure why we are + if (mLastKnownRequestMaturity == mLastKnownResponseMaturity) + { + llwarns << "Got an error but maturity preference '" << LLViewerRegion::accessToString(mLastKnownRequestMaturity) + << "' seems to be in sync with the server" << llendl; + reportPreferredMaturitySuccess(); + } + // Else, the more likely case is that the last request does not match the last response, + // so inform the user + else + { + reportPreferredMaturityError(); + } + } +} + +void LLAgent::reportPreferredMaturitySuccess() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, let's start the pending request + if (hasPendingTeleportRequest()) + { + startTeleportRequest(); + } +} + +void LLAgent::reportPreferredMaturityError() +{ + // If there is a pending teleport request waiting for the maturity preference to be synced with + // the server, we were unable to successfully sync with the server on maturity preference, so let's + // just raise the screen. + mIsMaturityRatingChangingDuringTeleport = false; + if (hasPendingTeleportRequest()) + { + setTeleportState(LLAgent::TELEPORT_NONE); + } + + // Get the last known maturity request from the user activity + std::string preferredMaturity = LLViewerRegion::accessToString(mLastKnownRequestMaturity); + LLStringUtil::toLower(preferredMaturity); + + // Get the last known maturity response from the server + std::string actualMaturity = LLViewerRegion::accessToString(mLastKnownResponseMaturity); + LLStringUtil::toLower(actualMaturity); + + // Notify the user + LLSD args = LLSD::emptyMap(); + args["PREFERRED_MATURITY"] = preferredMaturity; + args["ACTUAL_MATURITY"] = actualMaturity; + LLNotificationsUtil::add("MaturityChangeError", args); + + // Check the saved settings to ensure that we are consistent. If we are not consistent, update + // the viewer, but do not send anything to server + U8 localMaturity = static_cast(gSavedSettings.getU32("PreferredMaturity")); + if (localMaturity != mLastKnownResponseMaturity) + { + bool tmpIsDoSendMaturityPreferenceToServer = mIsDoSendMaturityPreferenceToServer; + mIsDoSendMaturityPreferenceToServer = false; + llinfos << "Setting viewer preferred maturity to '" << LLViewerRegion::accessToString(mLastKnownResponseMaturity) << "'" << llendl; + gSavedSettings.setU32("PreferredMaturity", static_cast(mLastKnownResponseMaturity)); + mIsDoSendMaturityPreferenceToServer = tmpIsDoSendMaturityPreferenceToServer; + } +} + +bool LLAgent::isMaturityPreferenceSyncedWithServer() const +{ + return (mMaturityPreferenceRequestId == mMaturityPreferenceResponseId); +} + +void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity) +{ + // Only send maturity preference to the server if enabled + if (mIsDoSendMaturityPreferenceToServer) + { + // Increment the number of requests. The handlers manage a separate count of responses. + ++mMaturityPreferenceRequestId; + + // Update the last know maturity request + mLastKnownRequestMaturity = pPreferredMaturity; + + // Create a response handler + boost::intrusive_ptr responderPtr = new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity); + + // If we don't have a region, report it as an error + if (getRegion() == NULL) + { + responderPtr->error(0U, "region is not defined"); + } + else + { + // Find the capability to send maturity preference + std::string url = getRegion()->getCapability("UpdateAgentInformation"); + + // If the capability is not defined, report it as an error + if (url.empty()) + { + responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region"); + } + else + { + // Set new access preference + LLSD access_prefs = LLSD::emptyMap(); + access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity); + + LLSD body = LLSD::emptyMap(); + body["access_prefs"] = access_prefs; + llinfos << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity) + << "' via capability to: " << url << llendl; + LLHTTPClient::post(url, body, responderPtr); + } + } } - return false; } BOOL LLAgent::getAdminOverride() const @@ -2429,6 +2790,12 @@ void LLAgent::setAdminOverride(BOOL b) void LLAgent::setGodLevel(U8 god_level) { mAgentAccess->setGodLevel(god_level); + mGodLevelChangeSignal(god_level); +} + +LLAgent::god_level_change_slot_t LLAgent::registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback) +{ + return mGodLevelChangeSignal.connect(pGodLevelChangeCallback); } void LLAgent::setAOTransition() @@ -2446,9 +2813,9 @@ bool LLAgent::validateMaturity(const LLSD& newvalue) return mAgentAccess->canSetMaturity(newvalue.asInteger()); } -void LLAgent::handleMaturity(const LLSD& newvalue) +void LLAgent::handleMaturity(const LLSD &pNewValue) { - sendMaturityPreferenceToServer(newvalue.asInteger()); + sendMaturityPreferenceToServer(static_cast(pNewValue.asInteger())); } void LLAgent::buildFullname(std::string& name) const @@ -3460,7 +3827,7 @@ void LLAgent::clearVisualParams(void *data) // protected bool LLAgent::teleportCore(bool is_local) { - if(TELEPORT_NONE != mTeleportState) + if ((TELEPORT_NONE != mTeleportState) && (mTeleportState != TELEPORT_PENDING)) { llwarns << "Attempt to teleport when already teleporting." << llendl; // @@ -3547,6 +3914,102 @@ bool LLAgent::teleportCore(bool is_local) return true; } +bool LLAgent::hasRestartableFailedTeleportRequest() +{ + return ((mTeleportRequest != NULL) && (mTeleportRequest->getStatus() == LLTeleportRequest::kFailed) && + mTeleportRequest->canRestartTeleport()); +} + +void LLAgent::restartFailedTeleportRequest() +{ + if (hasRestartableFailedTeleportRequest()) + { + mTeleportRequest->setStatus(LLTeleportRequest::kRestartPending); + startTeleportRequest(); + } +} + +void LLAgent::clearTeleportRequest() +{ + mTeleportRequest.reset(); +} + +void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange) +{ + mIsMaturityRatingChangingDuringTeleport = true; + mMaturityRatingChange = pMaturityRatingChange; +} + +bool LLAgent::hasPendingTeleportRequest() +{ + return ((mTeleportRequest != NULL) && + ((mTeleportRequest->getStatus() == LLTeleportRequest::kPending) || + (mTeleportRequest->getStatus() == LLTeleportRequest::kRestartPending))); +} + +void LLAgent::startTeleportRequest() +{ + if (hasPendingTeleportRequest()) + { + if (!isMaturityPreferenceSyncedWithServer()) + { + gTeleportDisplay = TRUE; + setTeleportState(TELEPORT_PENDING); + } + else + { + switch (mTeleportRequest->getStatus()) + { + case LLTeleportRequest::kPending : + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->startTeleport(); + break; + case LLTeleportRequest::kRestartPending : + llassert(mTeleportRequest->canRestartTeleport()); + mTeleportRequest->setStatus(LLTeleportRequest::kStarted); + mTeleportRequest->restartTeleport(); + break; + default : + llassert(0); + break; + } + } + } +} + +void LLAgent::handleTeleportFinished() +{ + clearTeleportRequest(); + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + +void LLAgent::handleTeleportFailed() +{ + if (mTeleportRequest != NULL) + { + mTeleportRequest->setStatus(LLTeleportRequest::kFailed); + } + if (mIsMaturityRatingChangingDuringTeleport) + { + // notify user that the maturity preference has been changed + std::string maturityRating = LLViewerRegion::accessToString(mMaturityRatingChange); + LLStringUtil::toLower(maturityRating); + LLSD args; + args["RATING"] = maturityRating; + LLNotificationsUtil::add("PreferredMaturityChanged", args); + mIsMaturityRatingChangingDuringTeleport = false; + } +} + void LLAgent::teleportRequest( const U64& region_handle, const LLVector3& pos_local, @@ -3593,7 +4056,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) return; } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLandmark(landmark_asset_id)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLandmark(const LLUUID& landmark_asset_id) +{ LLViewerRegion *regionp = getRegion(); if(regionp && teleportCore()) { @@ -3608,6 +4076,12 @@ void LLAgent::teleportViaLandmark(const LLUUID& landmark_asset_id) } void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) +{ + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLure(lure_id, godlike)); + startTeleportRequest(); +} + +void LLAgent::doTeleportViaLure(const LLUUID& lure_id, BOOL godlike) { LLViewerRegion* regionp = getRegion(); if(regionp && teleportCore()) @@ -3640,18 +4114,21 @@ void LLAgent::teleportViaLure(const LLUUID& lure_id, BOOL godlike) // James Cook, July 28, 2005 void LLAgent::teleportCancel() { - LLViewerRegion* regionp = getRegion(); - if(regionp) + if (!hasPendingTeleportRequest()) { - // send the message - LLMessageSystem* msg = gMessageSystem; - msg->newMessage("TeleportCancel"); - msg->nextBlockFast(_PREHASH_Info); - msg->addUUIDFast(_PREHASH_AgentID, getID()); - msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); - sendReliableMessage(); - } - gTeleportDisplay = FALSE; + LLViewerRegion* regionp = getRegion(); + if(regionp) + { + // send the message + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("TeleportCancel"); + msg->nextBlockFast(_PREHASH_Info); + msg->addUUIDFast(_PREHASH_AgentID, getID()); + msg->addUUIDFast(_PREHASH_SessionID, getSessionID()); + sendReliableMessage(); + } + } + clearTeleportRequest(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } @@ -3676,8 +4153,19 @@ void LLAgent::teleportViaLocation(const LLVector3d& pos_global) } } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocation(pos_global)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLocation(const LLVector3d& pos_global) +{ LLViewerRegion* regionp = getRegion(); + + if (!regionp) + { + return; + } + U64 handle = to_region_handle(pos_global); LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromHandle(handle); bool calc = gSavedSettings.getBOOL("OptionOffsetTPByAgentHeight"); @@ -3737,7 +4225,12 @@ void LLAgent::teleportViaLocationLookAt(const LLVector3d& pos_global) return; } // [/RLVa:KB] + mTeleportRequest = LLTeleportRequestPtr(new LLTeleportRequestViaLocationLookAt(pos_global)); + startTeleportRequest(); +} +void LLAgent::doTeleportViaLocationLookAt(const LLVector3d& pos_global) +{ mbTeleportKeepsLookAt = true; gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE); // detach camera form avatar, so it keeps direction U64 region_handle = to_region_handle(pos_global); @@ -4233,4 +4726,148 @@ LLAgentQueryManager::~LLAgentQueryManager() { } +//----------------------------------------------------------------------------- +// LLTeleportRequest +//----------------------------------------------------------------------------- + +LLTeleportRequest::LLTeleportRequest() + : mStatus(kPending) +{ +} + +LLTeleportRequest::~LLTeleportRequest() +{ +} + +bool LLTeleportRequest::canRestartTeleport() +{ + return false; +} + +void LLTeleportRequest::restartTeleport() +{ + llassert(0); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLandmark +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId) + : LLTeleportRequest(), + mLandmarkId(pLandmarkId) +{ +} + +LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark() +{ +} + +bool LLTeleportRequestViaLandmark::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLandmark::startTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +void LLTeleportRequestViaLandmark::restartTeleport() +{ + gAgent.doTeleportViaLandmark(getLandmarkId()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLure +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID &pLureId, BOOL pIsLureGodLike) + : LLTeleportRequestViaLandmark(pLureId), + mIsLureGodLike(pIsLureGodLike) +{ +} + +LLTeleportRequestViaLure::~LLTeleportRequestViaLure() +{ +} + +bool LLTeleportRequestViaLure::canRestartTeleport() +{ + // stinson 05/17/2012 : cannot restart a teleport via lure because of server-side restrictions + // The current scenario is as follows: + // 1. User A initializes a request for User B to teleport via lure + // 2. User B accepts the teleport via lure request + // 3. The server sees the init request from User A and the accept request from User B and matches them up + // 4. The server then removes the paired requests up from the "queue" + // 5. The server then fails User B's teleport for reason of maturity level (for example) + // 6. User B's viewer prompts user to increase their maturity level profile value. + // 7. User B confirms and accepts increase in maturity level + // 8. User B's viewer then attempts to teleport via lure again + // 9. This request will time-out on the viewer-side because User A's initial request has been removed from the "queue" in step 4 + + return false; +} + +void LLTeleportRequestViaLure::startTeleport() +{ + gAgent.doTeleportViaLure(getLandmarkId(), isLureGodLike()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocation +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocation::LLTeleportRequestViaLocation(const LLVector3d &pPosGlobal) + : LLTeleportRequest(), + mPosGlobal(pPosGlobal) +{ +} + +LLTeleportRequestViaLocation::~LLTeleportRequestViaLocation() +{ +} + +bool LLTeleportRequestViaLocation::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocation::startTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +void LLTeleportRequestViaLocation::restartTeleport() +{ + gAgent.doTeleportViaLocation(getPosGlobal()); +} + +//----------------------------------------------------------------------------- +// LLTeleportRequestViaLocationLookAt +//----------------------------------------------------------------------------- + +LLTeleportRequestViaLocationLookAt::LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal) + : LLTeleportRequestViaLocation(pPosGlobal) +{ +} + +LLTeleportRequestViaLocationLookAt::~LLTeleportRequestViaLocationLookAt() +{ +} + +bool LLTeleportRequestViaLocationLookAt::canRestartTeleport() +{ + return true; +} + +void LLTeleportRequestViaLocationLookAt::startTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} + +void LLTeleportRequestViaLocationLookAt::restartTeleport() +{ + gAgent.doTeleportViaLocationLookAt(getPosGlobal()); +} // EOF diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h index 82513766e..67dd6a3ff 100644 --- a/indra/newview/llagent.h +++ b/indra/newview/llagent.h @@ -47,6 +47,8 @@ #include "llinventorymodel.h" #include "v3dmath.h" +#include +#include #include extern const BOOL ANIMATE; @@ -67,8 +69,10 @@ class LLViewerObject; class LLAgentDropGroupViewerNode; class LLAgentAccess; class LLSimInfo; +class LLTeleportRequest; typedef std::vector llvo_vec_t; +typedef boost::shared_ptr LLTeleportRequestPtr; enum EAnimRequest { @@ -557,7 +561,8 @@ public: TELEPORT_MOVING = 3, // Viewer has received destination location from source simulator TELEPORT_START_ARRIVAL = 4, // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator TELEPORT_ARRIVING = 5, // Make the user wait while content "pre-caches" - TELEPORT_LOCAL = 6 // Teleporting in-sim without showing the progress screen + TELEPORT_LOCAL = 6, // Teleporting in-sim without showing the progress screen + TELEPORT_PENDING = 7 }; public: @@ -573,9 +578,6 @@ public: // Teleport Actions //-------------------------------------------------------------------- public: - void teleportRequest(const U64& region_handle, - const LLVector3& pos_local, // Go to a named location home - bool look_at_from_camera = false); void teleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark void teleportHome() { teleportViaLandmark(LLUUID::null); } // Go home void teleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location @@ -586,6 +588,44 @@ public: protected: bool teleportCore(bool is_local = false); // Stuff for all teleports; returns true if the teleport can proceed + //-------------------------------------------------------------------- + // Teleport State + //-------------------------------------------------------------------- + +public: + bool hasRestartableFailedTeleportRequest(); + void restartFailedTeleportRequest(); + void clearTeleportRequest(); + void setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange); + +private: + friend class LLTeleportRequest; + friend class LLTeleportRequestViaLandmark; + friend class LLTeleportRequestViaLure; + friend class LLTeleportRequestViaLocation; + friend class LLTeleportRequestViaLocationLookAt; + + LLTeleportRequestPtr mTeleportRequest; + boost::signals2::connection mTeleportFinishedSlot; + boost::signals2::connection mTeleportFailedSlot; + + bool mIsMaturityRatingChangingDuringTeleport; + U8 mMaturityRatingChange; + + bool hasPendingTeleportRequest(); + void startTeleportRequest(); + + void teleportRequest(const U64& region_handle, + const LLVector3& pos_local, // Go to a named location home + bool look_at_from_camera = false); + void doTeleportViaLandmark(const LLUUID& landmark_id); // Teleport to a landmark + void doTeleportViaLure(const LLUUID& lure_id, BOOL godlike); // To an invited location + void doTeleportViaLocation(const LLVector3d& pos_global); // To a global location - this will probably need to be deprecated + void doTeleportViaLocationLookAt(const LLVector3d& pos_global);// To a global location, preserving camera rotation + + void handleTeleportFinished(); + void handleTeleportFailed(); + //-------------------------------------------------------------------- // Teleport State //-------------------------------------------------------------------- @@ -648,6 +688,16 @@ public: void requestEnterGodMode(); void requestLeaveGodMode(); + typedef boost::function god_level_change_callback_t; + typedef boost::signals2::signal god_level_change_signal_t; + typedef boost::signals2::connection god_level_change_slot_t; + + god_level_change_slot_t registerGodLevelChanageListener(god_level_change_callback_t pGodLevelChangeCallback); + +private: + god_level_change_signal_t mGodLevelChangeSignal; + + //-------------------------------------------------------------------- // Maturity //-------------------------------------------------------------------- @@ -670,10 +720,25 @@ public: void setTeen(bool teen); void setMaturity(char text); static int convertTextToMaturity(char text); - bool sendMaturityPreferenceToServer(int preferredMaturity); // ! "U8" instead of "int"? +private: + bool mIsDoSendMaturityPreferenceToServer; + unsigned int mMaturityPreferenceRequestId; + unsigned int mMaturityPreferenceResponseId; + unsigned int mMaturityPreferenceNumRetries; + U8 mLastKnownRequestMaturity; + U8 mLastKnownResponseMaturity; + + bool isMaturityPreferenceSyncedWithServer() const; + void sendMaturityPreferenceToServer(U8 pPreferredMaturity); + + friend class LLMaturityPreferencesResponder; + void handlePreferredMaturityResult(U8 pServerMaturity); + void handlePreferredMaturityError(); + void reportPreferredMaturitySuccess(); + void reportPreferredMaturityError(); // Maturity callbacks for PreferredMaturity control variable - void handleMaturity(const LLSD& newvalue); + void handleMaturity(const LLSD &pNewValue); bool validateMaturity(const LLSD& newvalue); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a0c1481c7..a25086e04 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -3959,7 +3959,8 @@ void LLAppViewer::idle() } static const LLCachedControl hide_tp_screen("AscentDisableTeleportScreens",false); - if (!hide_tp_screen && gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL) + LLAgent::ETeleportState tp_state = gAgent.getTeleportState(); + if (!hide_tp_screen && tp_state != LLAgent::TELEPORT_NONE && tp_state != LLAgent::TELEPORT_LOCAL && tp_state != LLAgent::TELEPORT_PENDING) { return; } diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 12dd4a4b9..34b8785c9 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -638,22 +638,11 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) { - std::string first, last; std::string fullname; LLSD args; - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } - + LLSD payload; payload["from_id"] = agent_id; if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights) @@ -740,15 +729,11 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id, { // Popup a notify box with online status of this agent // Use display name only because this user is your friend + std::string name; + LLAvatarNameCache::getPNSName(av_name, name); LLSD args; - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : args["NAME"] = av_name.getLegacyName(); break; - case 1 : args["NAME"] = (av_name.mIsDisplayNameDefault ? av_name.mDisplayName : av_name.getCompleteName()); break; - case 2 : args["NAME"] = av_name.mDisplayName; break; - default : args["NAME"] = av_name.getCompleteName(); break; - } - + args["NAME"] = name; + // Popup a notify box with online status of this agent LLNotificationPtr notification = LLNotificationsUtil::add(online ? "FriendOnline" : "FriendOffline", args, payload); diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp index df9895906..d119f247f 100644 --- a/indra/newview/lldrawpoolwlsky.cpp +++ b/indra/newview/lldrawpoolwlsky.cpp @@ -54,7 +54,7 @@ LLPointer LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; static LLGLSLShader* cloud_shader = NULL; static LLGLSLShader* sky_shader = NULL; - +static LLGLSLShader* star_shader = NULL; LLDrawPoolWLSky::LLDrawPoolWLSky(void) : LLDrawPool(POOL_WL_SKY) @@ -113,6 +113,8 @@ void LLDrawPoolWLSky::beginRenderPass( S32 pass ) LLPipeline::sUnderWaterRender ? &gObjectFullbrightNoColorWaterProgram : &gWLCloudProgram; + + star_shader = &gCustomAlphaProgram; } void LLDrawPoolWLSky::endRenderPass( S32 pass ) @@ -123,6 +125,7 @@ void LLDrawPoolWLSky::beginDeferredPass(S32 pass) { sky_shader = &gDeferredWLSkyProgram; cloud_shader = &gDeferredWLCloudProgram; + star_shader = &gDeferredStarProgram; } void LLDrawPoolWLSky::endDeferredPass(S32 pass) @@ -182,6 +185,15 @@ void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const void LLDrawPoolWLSky::renderStars(void) const { + // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid + // clamping and allow the star_alpha param to brighten the stars. + bool error; + LLColor4 star_alpha(LLColor4::black); + star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; + llassert_always(!error); + if(star_alpha.mV[3] <= 0) + return; + LLGLSPipelineSkyBox gls_sky; LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -198,26 +210,16 @@ void LLDrawPoolWLSky::renderStars(void) const glPointSize(2.f); }*/ - // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid - // clamping and allow the star_alpha param to brighten the stars. - bool error; - LLColor4 star_alpha(LLColor4::black); - star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f; - llassert_always(!error); - + gGL.pushMatrix(); + gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); // gl_FragColor.rgb = gl_Color.rgb; // gl_FragColor.a = gl_Color.a * star_alpha.a; //New gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex()); - gGL.pushMatrix(); - gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f); - // gl_FragColor.rgb = gl_Color.rgb; - // gl_FragColor.a = gl_Color.a * star_alpha.a; - if (LLGLSLShader::sNoFixedFunction) + if (gPipeline.canUseVertexShaders()) { - gCustomAlphaProgram.bind(); - gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]); + star_shader->uniform1f("custom_alpha", star_alpha.mV[3]); } else { @@ -230,11 +232,7 @@ void LLDrawPoolWLSky::renderStars(void) const gGL.popMatrix(); - if (LLGLSLShader::sNoFixedFunction) - { - gCustomAlphaProgram.unbind(); - } - else + if (!gPipeline.canUseVertexShaders()) { // and disable the combiner states gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); @@ -261,8 +259,15 @@ void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const void LLDrawPoolWLSky::renderHeavenlyBodies() { + LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor(), gSky.mVOSkyp->getMoon().getDirection().mV[2]); + if (color.mV[VW] <= 0.f) + return; + + color.mV[VW] = llclamp(color.mV[VW]*color.mV[VW]*4.f,0.f,1.f); + LLGLSPipelineSkyBox gls_skybox; LLGLEnable blend_on(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); gPipeline.disableLights(); #if 0 // when we want to re-add a texture sun disc, here's where to do it. @@ -279,33 +284,31 @@ void LLDrawPoolWLSky::renderHeavenlyBodies() LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; - if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount()) + if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount() && face->getVertexBuffer()) { // *NOTE: even though we already bound this texture above for the // stars register combiners, we bind again here for defensive reasons, // since LLImageGL::bind detects that it's a noop, and optimizes it out. gGL.getTexUnit(0)->bind(face->getTexture()); - LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); - F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; - if (a > 0.f) - { - a = a*a*4.f; - } - - color.mV[3] = llclamp(a, 0.f, 1.f); if (gPipeline.canUseVertexShaders()) { - gHighlightProgram.bind(); + // Okay, so the moon isn't a star, but it's close enough. + star_shader->uniform1f("custom_alpha", color.mV[VW]); + } + else + { + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR); + gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA); + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color.mV); } - LLFacePool::LLOverrideFaceColor color_override(this, color); + face->getVertexBuffer()->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); + face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getVertexBuffer()->getNumIndices(), 0); - face->renderIndexed(); - - if (gPipeline.canUseVertexShaders()) + if (!gPipeline.canUseVertexShaders()) { - gHighlightProgram.unbind(); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } } } @@ -324,7 +327,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) LLGLDepthTest depth(GL_TRUE, GL_FALSE); LLGLDisable clip(GL_CLIP_PLANE0); - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); //Just in case. LLGLSquashToFarClip far_clip(glh_get_current_projection()); @@ -336,7 +339,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); - gDeferredStarProgram.bind(); + star_shader->bind(); // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only // bind the moon's texture once. @@ -346,13 +349,12 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass) renderStars(); - gDeferredStarProgram.unbind(); + star_shader->unbind(); gGL.popMatrix(); renderSkyClouds(camHeightLocal); - gGL.setColorMask(true, true); //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } @@ -373,6 +375,8 @@ void LLDrawPoolWLSky::render(S32 pass) LLGLSquashToFarClip far_clip(glh_get_current_projection()); + gGL.setColorMask(true, false); //Just in case. + renderSkyHaze(camHeightLocal); LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin(); @@ -380,6 +384,8 @@ void LLDrawPoolWLSky::render(S32 pass) gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]); + if(gPipeline.canUseVertexShaders()) + star_shader->bind(); // *NOTE: have to bind a texture here since register combiners blending in // renderStars() requires something to be bound and we might as well only // bind the moon's texture once. @@ -388,6 +394,9 @@ void LLDrawPoolWLSky::render(S32 pass) renderHeavenlyBodies(); renderStars(); + + if(gPipeline.canUseVertexShaders()) + star_shader->unbind(); gGL.popMatrix(); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index 5415c1acf..413398cf1 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -45,7 +45,7 @@ /*static*/ F32 LLVolumeImplFlexible::sUpdateFactor = 1.0f; std::vector LLVolumeImplFlexible::sInstanceList; -std::vector LLVolumeImplFlexible::sUpdateDelay; +std::vector LLVolumeImplFlexible::sUpdateDelay; static LLFastTimer::DeclareTimer FTM_FLEXIBLE_REBUILD("Rebuild"); static LLFastTimer::DeclareTimer FTM_DO_FLEXIBLE_UPDATE("Update"); @@ -96,14 +96,13 @@ LLVolumeImplFlexible::~LLVolumeImplFlexible() //static void LLVolumeImplFlexible::updateClass() { - std::vector::iterator delay_iter = sUpdateDelay.begin(); + std::vector::iterator delay_iter = sUpdateDelay.begin(); for (std::vector::iterator iter = sInstanceList.begin(); iter != sInstanceList.end(); ++iter) { - --(*delay_iter); - if (*delay_iter <= 0) + if(!*delay_iter || !--*delay_iter) { (*iter)->doIdleUpdate(); } @@ -360,6 +359,7 @@ void LLVolumeImplFlexible::doIdleUpdate() F32 pixel_area = mVO->getPixelArea(); U32 update_period = (U32) (LLViewerCamera::getInstance()->getScreenPixelArea()*0.01f/(pixel_area*(sUpdateFactor+1.f)))+1; + update_period = llclamp(update_period,1U,(U32)llmax((U32)llceil(gFPSClamped*2.f),32U)); if (visible) { @@ -380,7 +380,7 @@ void LLVolumeImplFlexible::doIdleUpdate() if ((LLDrawable::getCurrentFrame()+id)%update_period == 0) { - sUpdateDelay[mInstanceIndex] = (S32) update_period-1; + sUpdateDelay[mInstanceIndex] = update_period-1; updateRenderRes(); @@ -390,7 +390,7 @@ void LLVolumeImplFlexible::doIdleUpdate() } else { - sUpdateDelay[mInstanceIndex] = (S32) update_period; + sUpdateDelay[mInstanceIndex] = update_period; } } } diff --git a/indra/newview/llflexibleobject.h b/indra/newview/llflexibleobject.h index cba941bcd..d8b322546 100644 --- a/indra/newview/llflexibleobject.h +++ b/indra/newview/llflexibleobject.h @@ -72,11 +72,11 @@ class LLVolumeImplFlexible : public LLVolumeInterface { private: static std::vector sInstanceList; - static std::vector sUpdateDelay; + static std::vector sUpdateDelay; S32 mInstanceIndex; public: - static void resetTimers() { memset(&sUpdateDelay[0], 0, sizeof(S32)*sUpdateDelay.size()); } + static void resetTimers() { sUpdateDelay.assign(sUpdateDelay.size(),0); } static void updateClass(); LLVolumeImplFlexible(LLViewerObject* volume, LLFlexibleObjectData* attributes); diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp index 6c16dc94f..5eb9afa32 100644 --- a/indra/newview/llfloateractivespeakers.cpp +++ b/indra/newview/llfloateractivespeakers.cpp @@ -70,6 +70,8 @@ const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f); const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f); const F32 TYPING_ANIMATION_FPS = 2.5f; +static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name, std::string& mDisplayName); + LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerType type) : mStatus(LLSpeaker::STATUS_TEXT_ONLY), mLastSpokeTime(0.f), @@ -102,41 +104,22 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy void LLSpeaker::lookupName() { - // [Ansariel: Display name support] - LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onAvatarNameLookup, _1, _2, new LLHandle(getHandle()))); - // [/Ansariel: Display name support] + LLAvatarNameCache::get(mID, boost::bind(&on_avatar_name_lookup, _1, _2, boost::ref(mDisplayName))); + + // Also set the legacy name. We will need it to initiate a new + // IM session. + gCacheName->getFullName(mID, mLegacyName); + mLegacyName = LLCacheName::cleanFullName(mLegacyName); } -//static -// [Ansariel: Display name support] -void LLSpeaker::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data) -// [/Ansariel: Display name support] +static void on_avatar_name_lookup(const LLUUID&, const LLAvatarName& avatar_name, std::string& mDisplayName) { - LLSpeaker* speaker_ptr = ((LLHandle*)user_data)->get(); - delete (LLHandle*)user_data; - - if (speaker_ptr) - { - // [Ansariel: Display name support] - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : speaker_ptr->mDisplayName = avatar_name.getLegacyName(); break; - case 1 : speaker_ptr->mDisplayName = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : speaker_ptr->mDisplayName = avatar_name.mDisplayName; break; - default : speaker_ptr->mDisplayName = avatar_name.getLegacyName(); break; - } - - // Also set the legacy name. We will need it to initiate a new - // IM session. - speaker_ptr->mLegacyName = LLCacheName::cleanFullName(avatar_name.getLegacyName()); - // [/Ansariel: Display name support] - + LLAvatarNameCache::getPNSName(avatar_name, mDisplayName); // [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Added: RLVa-1.0.0g - // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventuall get fixed - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - speaker_ptr->mDisplayName = RlvStrings::getAnonym(speaker_ptr->mDisplayName); + // TODO-RLVa: this seems to get called per frame which is very likely an LL bug that will eventually get fixed + if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) + mDisplayName = RlvStrings::getAnonym(mDisplayName); // [/RLVa:KB] - } } LLSpeakerTextModerationEvent::LLSpeakerTextModerationEvent(LLSpeaker* source) diff --git a/indra/newview/llfloateractivespeakers.h b/indra/newview/llfloateractivespeakers.h index d641bcdf1..757c00bc7 100644 --- a/indra/newview/llfloateractivespeakers.h +++ b/indra/newview/llfloateractivespeakers.h @@ -77,11 +77,6 @@ public: ~LLSpeaker() {}; void lookupName(); - // [Ansariel: Display name support] - //static void onAvatarNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* user_data); - static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data); - // [/Ansariel: Display name support] - ESpeakerStatus mStatus; // current activity status in speech group F32 mLastSpokeTime; // timestamp when this speaker last spoke F32 mSpeechVolume; // current speech amplitude (timea average rms amplitude?) diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp index 015bb165e..2058df593 100644 --- a/indra/newview/llfloateravatarlist.cpp +++ b/indra/newview/llfloateravatarlist.cpp @@ -52,7 +52,9 @@ #include #include +#include #include +#include #include "llworld.h" #include "llsdutil.h" @@ -79,20 +81,24 @@ typedef enum e_radar_alert_type ALERT_TYPE_DRAW = 2, ALERT_TYPE_SHOUTRANGE = 4, ALERT_TYPE_CHATRANGE = 8, + ALERT_TYPE_AGE = 16, } ERadarAlertType; void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool entering) { + if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; //RLVa:LF Don't announce people are around when blind, that cheats the system. static LLCachedControl radar_chat_alerts(gSavedSettings, "RadarChatAlerts"); if (!radar_chat_alerts) return; static LLCachedControl radar_alert_sim(gSavedSettings, "RadarAlertSim"); static LLCachedControl radar_alert_draw(gSavedSettings, "RadarAlertDraw"); static LLCachedControl radar_alert_shout_range(gSavedSettings, "RadarAlertShoutRange"); static LLCachedControl radar_alert_chat_range(gSavedSettings, "RadarAlertChatRange"); + static LLCachedControl radar_alert_age(gSavedSettings, "RadarAlertAge"); static LLCachedControl radar_chat_keys(gSavedSettings, "RadarChatKeys"); LLFloaterAvatarList* self = LLFloaterAvatarList::getInstance(); LLStringUtil::format_map_t args; + args["[NAME]"] = name; switch(type) { case ALERT_TYPE_SIM: @@ -122,10 +128,21 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool args["[RANGE]"] = self->getString("chat_range"); } break; + + case ALERT_TYPE_AGE: + if (radar_alert_age) + { + LLChat chat; + chat.mFromName = name; + chat.mText = name + " " + self->getString("has_triggered_your_avatar_age_alert") + "."; + chat.mURL = llformat("secondlife:///app/agent/%s/about",key.asString().c_str()); + chat.mSourceType = CHAT_SOURCE_SYSTEM; + LLFloaterChat::addChat(chat); + } + break; } if (args.find("[RANGE]") != args.end()) { - args["[NAME]"] = name; args["[ACTION]"] = self->getString(entering ? "has_entered" : "has_left"); LLChat chat; chat.mText = self->getString("template", args); @@ -141,8 +158,33 @@ LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX), mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX), mActivityType(ACTIVITY_NEW), mActivityTimer(), - mIsInList(false) + mIsInList(false), mAge(-1), mAgeAlert(false), mTime(time(NULL)) { + if (mID.notNull()) + LLAvatarPropertiesProcessor::getInstance()->addObserver(mID, this); +} + +LLAvatarListEntry::~LLAvatarListEntry() +{ + if (mID.notNull()) + LLAvatarPropertiesProcessor::getInstance()->removeObserver(mID, this); +} + +// virtual +void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type) +{ + if(type == APT_PROPERTIES) + { + const LLAvatarData* pAvatarData = static_cast(data); + if (pAvatarData && (pAvatarData->avatar_id != LLUUID::null)) + { + using namespace boost::gregorian; + int year, month, day; + sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); + mAge = (day_clock::local_day() - date(year, month, day)).days(); + // If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it. + } + } } void LLAvatarListEntry::setPosition(LLVector3d position, bool this_sim, bool drawn, bool chatrange, bool shoutrange) @@ -353,6 +395,13 @@ BOOL LLFloaterAvatarList::postBuild() getChild("update_rate")->setSelectedIndex(gSavedSettings.getU32("RadarUpdateRate")); getChild("update_rate")->setCommitCallback(boost::bind(&LLFloaterAvatarList::onCommitUpdateRate, this)); + getChild("hide_mark")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_pos")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_alt")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_act")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_age")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + getChild("hide_time")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); + // Get a pointer to the scroll list from the interface mAvatarList = getChild("avatar_list"); mAvatarList->sortByColumn("distance", TRUE); @@ -364,20 +413,69 @@ BOOL LLFloaterAvatarList::postBuild() gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle); - if(gHippoGridManager->getConnectedGrid()->isSecondLife()){ - LLScrollListCtrl* list = getChild("avatar_list"); - list->getColumn(LIST_AVATAR_NAME)->setWidth(0); - list->getColumn(LIST_CLIENT)->setWidth(0); - list->getColumn(LIST_CLIENT)->mDynamicWidth = FALSE; - list->getColumn(LIST_CLIENT)->mRelWidth = 0; - list->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = TRUE; - list->getColumn(LIST_AVATAR_NAME)->mRelWidth = -1; - list->updateLayout(); - } + assessColumns(); + + if(gHippoGridManager->getConnectedGrid()->isSecondLife()) + childSetVisible("hide_client", false); + else + getChild("hide_client")->setCommitCallback(boost::bind(&LLFloaterAvatarList::assessColumns, this)); return TRUE; } +void col_helper(const bool hide, const std::string width_ctrl_name, LLScrollListColumn* col) +{ + // Brief Explanation: + // Check if we want the column hidden, and if it's still showing. If so, hide it, but save its width. + // Otherwise, if we don't want it hidden, but it is, unhide it to the saved width. + // We only store width of columns when hiding here for the purpose of hiding and unhiding. + const int width = col->getWidth(); + + if (hide && width) + { + gSavedSettings.setS32(width_ctrl_name, width); + col->setWidth(0); + } + else if(!hide && !width) + { + llinfos << "We got into the setter!!" << llendl; + col->setWidth(gSavedSettings.getS32(width_ctrl_name)); + } +} + +void LLFloaterAvatarList::assessColumns() +{ + static LLCachedControl hide_mark(gSavedSettings, "RadarColumnMarkHidden"); + col_helper(hide_mark, "RadarColumnMarkWidth", mAvatarList->getColumn(LIST_MARK)); + + static LLCachedControl hide_pos(gSavedSettings, "RadarColumnPositionHidden"); + col_helper(hide_pos, "RadarColumnPositionWidth", mAvatarList->getColumn(LIST_POSITION)); + + static LLCachedControl hide_alt(gSavedSettings, "RadarColumnAltitudeHidden"); + col_helper(hide_alt, "RadarColumnAltitudeWidth", mAvatarList->getColumn(LIST_ALTITUDE)); + + static LLCachedControl hide_act(gSavedSettings, "RadarColumnActivityHidden"); + col_helper(hide_act, "RadarColumnActivityWidth", mAvatarList->getColumn(LIST_ACTIVITY)); + + static LLCachedControl hide_age(gSavedSettings, "RadarColumnAgeHidden"); + col_helper(hide_age, "RadarColumnAgeWidth", mAvatarList->getColumn(LIST_AGE)); + + static LLCachedControl hide_time(gSavedSettings, "RadarColumnTimeHidden"); + col_helper(hide_time, "RadarColumnTimeWidth", mAvatarList->getColumn(LIST_TIME)); + + static LLCachedControl hide_client(gSavedSettings, "RadarColumnClientHidden"); + if (gHippoGridManager->getConnectedGrid()->isSecondLife() || hide_client){ + mAvatarList->getColumn(LIST_AVATAR_NAME)->setWidth(0); + mAvatarList->getColumn(LIST_CLIENT)->setWidth(0); + mAvatarList->getColumn(LIST_CLIENT)->mDynamicWidth = FALSE; + mAvatarList->getColumn(LIST_CLIENT)->mRelWidth = 0; + mAvatarList->getColumn(LIST_AVATAR_NAME)->mDynamicWidth = TRUE; + mAvatarList->getColumn(LIST_AVATAR_NAME)->mRelWidth = -1; + } + + mAvatarList->updateLayout(); +} + void updateParticleActivity(LLDrawable *drawablep) { if (LLFloaterAvatarList::instanceExists()) @@ -462,8 +560,6 @@ void LLFloaterAvatarList::updateAvatarList() for (i = 0; i < count; ++i) { std::string name; - std::string first; - std::string last; const LLUUID &avid = avatar_ids[i]; LLVector3d position; @@ -483,29 +579,13 @@ void LLFloaterAvatarList::updateAvatarList() position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition()); name = avatarp->getFullname(); - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(avatarp->getID(), &avatar_name)) - { - static LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : name = avatar_name.getLegacyName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getLegacyName(); break; - } - - first = avatar_name.mLegacyFirstName; - last = avatar_name.mLegacyLastName; - } - else continue; - // [/Ansariel: Display name support] + if (!LLAvatarNameCache::getPNSName(avatarp->getID(), name)) + continue; //duped for lower section if (name.empty() || (name.compare(" ") == 0))// || (name.compare(gCacheName->getDefaultName()) == 0)) { - if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::get above... + if (!gCacheName->getFullName(avid, name)) //seems redudant with LLAvatarNameCache::getPNSName above... { continue; } @@ -545,7 +625,7 @@ void LLFloaterAvatarList::updateAvatarList() continue; } - if (!gCacheName->getFullName(avid, name)) + if (!LLAvatarNameCache::getPNSName(avid, name)) { //name = gCacheName->getDefaultName(); continue; //prevent (Loading...) @@ -733,6 +813,10 @@ void LLFloaterAvatarList::refreshAvatarList() continue; } + //Request properties here, so we'll have them later on when we need them + LLAvatarPropertiesProcessor::getInstance()->addObserver(entry.mID, &entry); + LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(entry.mID); + element["id"] = av_id; element["columns"][LIST_MARK]["column"] = "marked"; @@ -772,6 +856,7 @@ void LLFloaterAvatarList::refreshAvatarList() static LLCachedControl sRadarTextChatRange(gColors, "RadarTextChatRange"); static LLCachedControl sRadarTextShoutRange(gColors, "RadarTextShoutRange"); static LLCachedControl sRadarTextDrawDist(gColors, "RadarTextDrawDist"); + static LLCachedControl sRadarTextYoung(gColors, "RadarTextYoung"); LLColor4 name_color = sDefaultListText; //Lindens are always more Linden than your friend, make that take precedence @@ -889,28 +974,50 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_ACTIVITY]["type"] = "icon"; std::string activity_icon = ""; + std::string activity_tip = ""; switch(entry.getActivity()) { case LLAvatarListEntry::ACTIVITY_MOVING: - activity_icon = "inv_item_animation.tga"; + { + activity_icon = "inv_item_animation.tga"; + activity_tip = getString("Moving"); + } break; case LLAvatarListEntry::ACTIVITY_GESTURING: - activity_icon = "inv_item_gesture.tga"; + { + activity_icon = "inv_item_gesture.tga"; + activity_tip = getString("Playing a gesture"); + } break; case LLAvatarListEntry::ACTIVITY_SOUND: - activity_icon = "inv_item_sound.tga"; + { + activity_icon = "inv_item_sound.tga"; + activity_tip = getString("Playing a sound"); + } break; case LLAvatarListEntry::ACTIVITY_REZZING: - activity_icon = "ff_edit_theirs.tga"; + { + activity_icon = "ff_edit_theirs.tga"; + activity_tip = getString("Rezzing objects"); + } break; case LLAvatarListEntry::ACTIVITY_PARTICLES: - activity_icon = "particles_scan.tga"; + { + activity_icon = "particles_scan.tga"; + activity_tip = getString("Creating particles"); + } break; case LLAvatarListEntry::ACTIVITY_NEW: - activity_icon = "avatar_new.tga"; + { + activity_icon = "avatar_new.tga"; + activity_tip = getString("Just arrived"); + } break; case LLAvatarListEntry::ACTIVITY_TYPING: - activity_icon = "avatar_typing.tga"; + { + activity_icon = "avatar_typing.tga"; + activity_tip = getString("Typing"); + } break; default: break; @@ -918,6 +1025,40 @@ void LLFloaterAvatarList::refreshAvatarList() element["columns"][LIST_ACTIVITY]["value"] = activity_icon;//icon_image_id; //"icn_active-speakers-dot-lvl0.tga"; //element["columns"][LIST_AVATAR_ACTIVITY]["color"] = icon_color.getValue(); + element["columns"][LIST_ACTIVITY]["tool_tip"] = activity_tip; + + element["columns"][LIST_AGE]["column"] = "age"; + element["columns"][LIST_AGE]["type"] = "text"; + color = sDefaultListText; + std::string age = boost::lexical_cast(entry.mAge); + if (entry.mAge > -1) + { + static LLCachedControl sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays"); + if ((U32)entry.mAge < sAvatarAgeAlertDays) + { + color = sRadarTextYoung; + if (!entry.mAgeAlert) //Only announce age once per entry. + { + entry.mAgeAlert = true; + chat_avatar_status(entry.getName().c_str(), av_id, ALERT_TYPE_AGE, true); + } + } + } + else + { + age = "?"; + } + element["columns"][LIST_AGE]["value"] = age; + element["columns"][LIST_AGE]["color"] = color.getValue(); + + int dur = difftime(time(NULL), entry.getTime()); + int hours = dur / 3600; + int mins = (dur % 3600) / 60; + int secs = (dur % 3600) % 60; + + element["columns"][LIST_TIME]["column"] = "time"; + element["columns"][LIST_TIME]["type"] = "text"; + element["columns"][LIST_TIME]["value"] = llformat("%d:%02d:%02d", hours, mins, secs); element["columns"][LIST_CLIENT]["column"] = "client"; element["columns"][LIST_CLIENT]["type"] = "text"; @@ -967,6 +1108,17 @@ void LLFloaterAvatarList::refreshAvatarList() mDirtyAvatarSorting = true; + if (mAvatars.empty()) + setTitle(getString("Title")); + else if (mAvatars.size() == 1) + setTitle(getString("TitleOneAvatar")); + else + { + LLStringUtil::format_map_t args; + args["[COUNT]"] = boost::lexical_cast(mAvatars.size()); + setTitle(getString("TitleWithCount", args)); + } + // llinfos << "radar refresh: done" << llendl; } @@ -982,14 +1134,12 @@ void LLFloaterAvatarList::onClickIM() // Single avatar LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string avatar_name; + if (gCacheName->getFullName(agent_id, avatar_name)) { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(avatar_name,IM_NOTHING_SPECIAL,agent_id); } - // [Ansariel: Display name support] } else { @@ -1114,14 +1264,12 @@ BOOL LLFloaterAvatarList::handleKeyHere(KEY key, MASK mask) // Single avatar LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string avatar_name; + if (gCacheName->getFullName(agent_id, avatar_name)) { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(avatar_name,IM_NOTHING_SPECIAL,agent_id); } - // [Ansariel: Display name support] } else { diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h index d9fe93581..8aa3d3665 100644 --- a/indra/newview/llfloateravatarlist.h +++ b/indra/newview/llfloateravatarlist.h @@ -11,6 +11,7 @@ // // #include "llavatarname.h" +#include "llavatarpropertiesprocessor.h" #include "llfloater.h" #include "llfloaterreporter.h" #include "lluuid.h" @@ -29,7 +30,8 @@ class LLFloaterAvatarList; * Instances are kept in a map. We keep track of the * frame where the avatar was last seen. */ -class LLAvatarListEntry { +class LLAvatarListEntry : public LLAvatarPropertiesObserver +{ public: @@ -52,6 +54,10 @@ enum ACTIVITY_TYPE * @param position Avatar's current position */ LLAvatarListEntry(const LLUUID& id = LLUUID::null, const std::string &name = "", const LLVector3d &position = LLVector3d::zero); + ~LLAvatarListEntry(); + + // Get properties, such as age and other niceties displayed on profiles. + /*virtual*/ void processProperties(void* data, EAvatarProcessorType type); /** * Update world position. @@ -78,6 +84,7 @@ enum ACTIVITY_TYPE * @brief Returns the name of the avatar */ const std::string& getName() const { return mName; } + const time_t& getTime() const { return mTime; } /** * @brief Returns the ID of the avatar @@ -132,11 +139,14 @@ private: LLUUID mID; std::string mName; + time_t mTime; LLVector3d mPosition; LLVector3d mDrawPosition; bool mMarked; bool mFocused; bool mIsInList; + bool mAgeAlert; + int mAge; /** * @brief Timer to keep track of whether avatars are still there @@ -202,6 +212,9 @@ public: static void showInstance(); + // Decides which user-chosen columns to show and hide. + void assessColumns(); + /** * @brief Updates the internal avatar list with the currently present avatars. */ @@ -245,6 +258,8 @@ private: LIST_POSITION, LIST_ALTITUDE, LIST_ACTIVITY, + LIST_AGE, + LIST_TIME, LIST_CLIENT, }; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index 6d6d1e251..dc0ad358c 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -33,24 +33,26 @@ #include "llfloateravatarpicker.h" -#include "message.h" - +// Viewer includes #include "llagent.h" -#include "llbutton.h" -#include "llcachename.h" #include "llfocusmgr.h" #include "llfoldervieweventlistener.h" -#include "llinventorypanel.h" -#include "llinventorymodel.h" #include "llinventoryfunctions.h" +#include "llinventorymodel.h" +#include "llinventorypanel.h" +#include "llviewercontrol.h" +#include "llviewerregion.h" +#include "llworld.h" + +// Linden libraries #include "llavatarnamecache.h" // IDEVO +#include "llbutton.h" +#include "llcachename.h" #include "lllineeditor.h" #include "llscrolllistctrl.h" #include "lltextbox.h" #include "lluictrlfactory.h" -#include "llviewercontrol.h" -#include "llworld.h" -#include "llviewerregion.h" +#include "message.h" // [RLVa:KB] #include "rlvhandler.h" diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp index f5786c46c..40af23889 100644 --- a/indra/newview/llfloaterfriends.cpp +++ b/indra/newview/llfloaterfriends.cpp @@ -44,10 +44,7 @@ #include "llagent.h" #include "llappviewer.h" // for gLastVersionChannel -// [Ansariel: Display name support] -#include "llavatarname.h" #include "llavatarnamecache.h" -// [/Ansariel: Display name support] #include "llfloateravatarpicker.h" #include "llviewerwindow.h" @@ -78,7 +75,7 @@ #include "llfloaterchat.h" // stuff for Contact groups -#include "ascentfloatercontactgroups.h" +//#include "ascentfloatercontactgroups.h" #define DEFAULT_PERIOD 5.0 #define RIGHTS_CHANGE_TIMEOUT 5.0 @@ -87,18 +84,40 @@ #define ONLINE_SIP_ICON_NAME "slim_icon_16_viewer.tga" // simple class to observe the calling cards. -class LLLocalFriendsObserver : public LLFriendObserver, public LLEventTimer + + +class LLAvatarListUpdater : public LLEventTimer { -public: - LLLocalFriendsObserver(LLPanelFriends* floater) : mFloater(floater), LLEventTimer(OBSERVER_TIMEOUT) +public: + LLAvatarListUpdater(F32 period) + : LLEventTimer(period) { mEventTimer.stop(); } - virtual ~LLLocalFriendsObserver() + + virtual BOOL tick() // from LLEventTimer { - mFloater = NULL; + return FALSE; } - virtual void changed(U32 mask) +}; + +class LLLocalFriendsObserver : public LLAvatarListUpdater, public LLFriendObserver +{ + LOG_CLASS(LLLocalFriendsObserver); +public: + LLLocalFriendsObserver(LLPanelFriends* floater) + : mFloater(floater), LLAvatarListUpdater(OBSERVER_TIMEOUT) + { + LLAvatarTracker::instance().addObserver(this); + // For notification when SIP online status changes. + LLVoiceClient::getInstance()->addObserver(this); + } + /*virtual*/ ~LLLocalFriendsObserver() + { + LLVoiceClient::getInstance()->removeObserver(this); + LLAvatarTracker::instance().removeObserver(this); + } + /*virtual*/ void changed(U32 mask) { // events can arrive quickly in bulk - we need not process EVERY one of them - // so we wait a short while to let others pile-in, and process them in aggregate. @@ -107,9 +126,9 @@ public: // save-up all the mask-bits which have come-in mMask |= mask; } - virtual BOOL tick() + /*virtual*/ BOOL tick() { - mFloater->populateContactGroupSelect(); + //mFloater->populateContactGroupSelect(); mFloater->updateFriends(mMask); mEventTimer.stop(); @@ -134,16 +153,10 @@ LLPanelFriends::LLPanelFriends() : { mEventTimer.stop(); mObserver = new LLLocalFriendsObserver(this); - LLAvatarTracker::instance().addObserver(mObserver); - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->addObserver(mObserver); } LLPanelFriends::~LLPanelFriends() { - // For notification when SIP online status changes. - LLVoiceClient::getInstance()->removeObserver(mObserver); - LLAvatarTracker::instance().removeObserver(mObserver); delete mObserver; } @@ -218,7 +231,7 @@ std::string LLPanelFriends::cleanFileName(std::string filename) return filename; } -void LLPanelFriends::populateContactGroupSelect() +/*void LLPanelFriends::populateContactGroupSelect() { LLComboBox* combo = getChild("buddy_group_combobox"); @@ -241,18 +254,18 @@ void LLPanelFriends::populateContactGroupSelect() LLChat msg("Null combo"); LLFloaterChat::addChat(msg); } -} +}*/ -void LLPanelFriends::setContactGroup(std::string contact_grp) +/*void LLPanelFriends::setContactGroup(std::string contact_grp) { LLChat msg("Group set to " + contact_grp); LLFloaterChat::addChat(msg); refreshNames(LLFriendObserver::ADD); refreshUI(); categorizeContacts(); -} +}*/ -void LLPanelFriends::categorizeContacts() +/*void LLPanelFriends::categorizeContacts() { LLSD contact_groups = gSavedPerAccountSettings.getLLSD("AscentContactGroups"); std::string group_name = "All"; @@ -306,7 +319,7 @@ void LLPanelFriends::categorizeContacts() LLChat msg("Null combo."); LLFloaterChat::addChat(msg); } -} +}*/ void LLPanelFriends::filterContacts(const std::string& search_name) { @@ -350,7 +363,7 @@ void LLPanelFriends::onContactSearchEdit(const std::string& search_string, void* } } -void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) +/*void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; @@ -359,7 +372,7 @@ void LLPanelFriends::onChangeContactGroup(LLUICtrl* ctrl, void* user_data) LLComboBox* combo = panelp->getChild("buddy_group_combobox"); panelp->setContactGroup(combo->getValue().asString()); } -} +}*/ // -- // virtual @@ -368,7 +381,7 @@ BOOL LLPanelFriends::postBuild() mFriendsList = getChild("friend_list"); mFriendsList->setCommitOnSelectionChange(TRUE); mFriendsList->setCommitCallback(onSelectName, this); - childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); + //childSetCommitCallback("buddy_group_combobox", onChangeContactGroup, this); mFriendsList->setDoubleClickCallback(onClickIM, this); // @@ -387,7 +400,7 @@ BOOL LLPanelFriends::postBuild() refreshNames(changed_mask); childSetAction("im_btn", onClickIM, this); - childSetAction("assign_btn", onClickAssign, this); + //childSetAction("assign_btn", onClickAssign, this); childSetAction("expand_collapse_btn", onClickExpand, this); childSetAction("profile_btn", onClickProfile, this); childSetAction("offer_teleport_btn", onClickOfferTeleport, this); @@ -421,26 +434,8 @@ BOOL LLPanelFriends::addFriend(const LLUUID& agent_id) bool isOnline = relationInfo->isOnline(); std::string fullname; - // [Ansariel: Display name support] - //BOOL have_name = gCacheName->getFullName(agent_id, fullname); - LLAvatarName avatar_name; - BOOL have_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } + BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); - have_name = TRUE; - } - else have_name = FALSE; - // [/Ansariel: Display name support] - LLSD element; element["id"] = agent_id; LLSD& friend_column = element["columns"][LIST_FRIEND_NAME]; @@ -520,26 +515,8 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh bool isOnlineSIP = LLVoiceClient::getInstance()->isOnlineSIP(itemp->getUUID()); bool isOnline = info->isOnline(); - std::string fullname; - // [Ansariel: Display name support] - //BOOL have_name = gCacheName->getFullName(agent_id, fullname); - LLAvatarName avatar_name; - BOOL have_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - - have_name = TRUE; - } - else have_name = FALSE; - // [/Ansariel: Display name support] + std::string fullname; + BOOL have_name = LLAvatarNameCache::getPNSName(agent_id, fullname); // Name of the status icon to use std::string statusIcon; @@ -580,6 +557,8 @@ BOOL LLPanelFriends::updateFriendItem(const LLUUID& agent_id, const LLRelationsh // enable this item, in case it was disabled after user input itemp->setEnabled(TRUE); + mFriendsList->setNeedsSort(); + // Do not resort, this function can be called frequently. return have_name; } @@ -635,7 +614,7 @@ void LLPanelFriends::refreshRightsChangeList() if (num_selected == 0) // nothing selected { childSetEnabled("im_btn", FALSE); - childSetEnabled("assign_btn", FALSE); + //childSetEnabled("assign_btn", FALSE); childSetEnabled("offer_teleport_btn", FALSE); } else // we have at least one friend selected... @@ -644,7 +623,7 @@ void LLPanelFriends::refreshRightsChangeList() // to be consistent with context menus in inventory and because otherwise // offline friends would be silently dropped from the session childSetEnabled("im_btn", selected_friends_online || num_selected == 1); - childSetEnabled("assign_btn", num_selected == 1); + //childSetEnabled("assign_btn", num_selected == 1); childSetEnabled("offer_teleport_btn", can_offer_teleport); } } @@ -776,7 +755,7 @@ void LLPanelFriends::refreshUI() //Options that can only be performed with one friend selected childSetEnabled("profile_btn", single_selected && !multiple_selected); childSetEnabled("pay_btn", single_selected && !multiple_selected); - childSetEnabled("assign_btn", single_selected && !multiple_selected); + //childSetEnabled("assign_btn", single_selected && !multiple_selected); //Options that can be performed with up to MAX_FRIEND_SELECT friends selected //(single_selected will always be true in this situations) @@ -817,7 +796,7 @@ void LLPanelFriends::onClickProfile(void* user_data) } // static -void LLPanelFriends::onClickAssign(void* user_data) +/*void LLPanelFriends::onClickAssign(void* user_data) { LLPanelFriends* panelp = (LLPanelFriends*)user_data; if (panelp) @@ -825,7 +804,7 @@ void LLPanelFriends::onClickAssign(void* user_data) const uuid_vec_t ids = panelp->mFriendsList->getSelectedIDs(); ASFloaterContactGroups::show(ids); } -} +}*/ // static void LLPanelFriends::onClickExpand(void* user_data) @@ -880,20 +859,12 @@ void LLPanelFriends::onClickIM(void* user_data) { LLUUID agent_id = ids[0]; const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(agent_id); - // [Ansariel: Display name support] - //std::string fullname; - //if(info && gCacheName->getFullName(agent_id, fullname)) - //{ - // gIMMgr->setFloaterOpen(TRUE); - // gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id); - //} - LLAvatarName avatar_name; - if (info && LLAvatarNameCache::get(agent_id, &avatar_name)) + std::string fullname; + if(info && gCacheName->getFullName(agent_id, fullname)) { gIMMgr->setFloaterOpen(TRUE); - gIMMgr->addSession(LLCacheName::cleanFullName(avatar_name.getLegacyName()),IM_NOTHING_SPECIAL,agent_id); + gIMMgr->addSession(fullname, IM_NOTHING_SPECIAL, agent_id); } - // [/Ansariel: Display name support] } else { @@ -1009,30 +980,9 @@ void LLPanelFriends::onClickRemove(void* user_data) if(ids.size() == 1) { LLUUID agent_id = ids[0]; - // [Ansariel: Display name support] - //std::string first, last; - //if(gCacheName->getName(agent_id, first, last)) - //{ - // args["FIRST_NAME"] = first; - // args["LAST_NAME"] = last; - //} - - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - std::string fullname; - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - + std::string fullname; + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } - // [/Ansariel: Display name support] } else { @@ -1276,28 +1226,9 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command if(ids.size() == 1) { LLUUID agent_id = ids.begin()->first; - //std::string first, last; - //if(gCacheName->getName(agent_id, first, last)) - //{ - // args["FIRST_NAME"] = first; - // args["LAST_NAME"] = last; - //} - - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(agent_id, &avatar_name)) - { - std::string fullname; - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : fullname = avatar_name.getLegacyName(); break; - case 1 : fullname = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : fullname = avatar_name.mDisplayName; break; - default : fullname = avatar_name.getCompleteName(); break; - } - + std::string fullname; + if (LLAvatarNameCache::getPNSName(agent_id, fullname)) args["NAME"] = fullname; - } if (command == GRANT) { @@ -1394,6 +1325,7 @@ void LLPanelFriends::applyRightsToFriends() rights &= ~LLRelationship::GRANT_MAP_LOCATION; // propagate rights constraint to UI (*itr)->getColumn(LIST_VISIBLE_MAP)->setValue(FALSE); + mFriendsList->setNeedsSortColumn(LIST_VISIBLE_MAP); } } if(buddy_relationship->isRightGrantedTo(LLRelationship::GRANT_MAP_LOCATION) != show_map_location) @@ -1405,6 +1337,7 @@ void LLPanelFriends::applyRightsToFriends() rights |= LLRelationship::GRANT_MAP_LOCATION; rights |= LLRelationship::GRANT_ONLINE_STATUS; (*itr)->getColumn(LIST_VISIBLE_ONLINE)->setValue(TRUE); + mFriendsList->setNeedsSortColumn(LIST_VISIBLE_ONLINE); } else { diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 054d8b1f3..ab3f45aff 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -1628,9 +1628,9 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo row.append(time_column); if( is_group_owned ) - self->mOwnerList->addGroupNameItem(row, ADD_BOTTOM); + self->mOwnerList->addGroupNameItem(item, ADD_BOTTOM); else - self->mOwnerList->addNameItem(row, ADD_BOTTOM); + self->mOwnerList->addNameItem(item, ADD_BOTTOM); lldebugs << "object owner " << owner_id << " (" << (is_group_owned ? "group" : "agent") << ") owns " << object_count << " objects." << llendl; diff --git a/indra/newview/llfloatermute.cpp b/indra/newview/llfloatermute.cpp index aebb4009a..624c244a4 100644 --- a/indra/newview/llfloatermute.cpp +++ b/indra/newview/llfloatermute.cpp @@ -48,14 +48,16 @@ #include "llbutton.h" #include "lllineeditor.h" #include "llmutelist.h" +#include "llnamelistctrl.h" #include "llresizehandle.h" -#include "llscrolllistctrl.h" #include "lltextbox.h" #include "llviewertexteditor.h" #include "llviewerwindow.h" #include "lluictrlfactory.h" #include "llfocusmgr.h" +#include + // // Constants // @@ -209,7 +211,12 @@ BOOL LLFloaterMute::postBuild() childSetAction("Mute object by name...", onClickMuteByName, this); childSetAction("Unmute", onClickRemove, this); - mMuteList = getChild("mutes"); + mAvatarIcon = LLUI::getUIImage("icon_avatar_offline.tga"); + mObjectIcon = LLUI::getUIImage("inv_item_object.tga"); + mGroupIcon = LLUI::getUIImage("icon_group.tga"); + mNameIcon = LLUI::getUIImage("icon_name.tga"); + + mMuteList = getChild("mutes"); mMuteList->setCommitOnSelectionChange(TRUE); LLMuteList::getInstance()->addObserver(this); @@ -231,16 +238,63 @@ LLFloaterMute::~LLFloaterMute() //----------------------------------------------------------------------------- void LLFloaterMute::refreshMuteList() { + uuid_vec_t selected = mMuteList->getSelectedIDs(); + S32 scrollpos = mMuteList->getScrollPos(); + mMuteList->deleteAllItems(); + mMuteDict.clear(); std::vector mutes = LLMuteList::getInstance()->getMutes(); std::vector::iterator it; + U32 count = 0; for (it = mutes.begin(); it != mutes.end(); ++it) { - std::string display_name = it->getDisplayName(); - mMuteList->addStringUUIDItem(display_name, it->mID); - } + std::string display_name = it->mName; + LLSD element; + LLUUID entry_id; + if(it->mType == LLMute::GROUP || it->mType == LLMute::AGENT) + entry_id = it->mID; + else + entry_id.generate(boost::lexical_cast( count++ )); + mMuteDict.insert(std::make_pair(entry_id,*it)); + element["id"] = entry_id; + element["name"] = display_name; + LLSD& name_column = element["columns"][1]; + name_column["column"] = "name"; + name_column["type"] = "text"; + name_column["value"] = ""; + + LLSD& icon_column = element["columns"][0]; + icon_column["column"] = "icon"; + icon_column["type"] = "icon"; + + switch(it->mType) + { + case LLMute::GROUP: + icon_column["value"] = mGroupIcon->getName(); + element["target"] = LLNameListCtrl::GROUP; + break; + case LLMute::AGENT: + icon_column["value"] = mAvatarIcon->getName(); + element["target"] = LLNameListCtrl::INDIVIDUAL; + break; + case LLMute::OBJECT: + icon_column["value"] = mObjectIcon->getName(); + element["target"] = LLNameListCtrl::SPECIAL; + break; + case LLMute::BY_NAME: + default: + icon_column["value"] = mNameIcon->getName(); + element["target"] = LLNameListCtrl::SPECIAL; + + break; + } + mMuteList->addNameItemRow(element); + } + mMuteList->updateSort(); + mMuteList->selectMultiple(selected); + mMuteList->setScrollPos(scrollpos); updateButtons(); } @@ -282,17 +336,22 @@ void LLFloaterMute::onClickRemove(void *data) { LLFloaterMute* floater = (LLFloaterMute *)data; - std::string name = floater->mMuteList->getSelectedItemLabel(); - LLUUID id = floater->mMuteList->getStringUUIDSelectedItem(); - LLMute mute(id); - mute.setFromDisplayName(name); - // now mute.mName has the suffix trimmed off - S32 last_selected = floater->mMuteList->getFirstSelectedIndex(); - if (LLMuteList::getInstance()->remove(mute)) + bool removed = false; + const std::vector items = floater->mMuteList->getAllSelected(); + for(std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + { + std::map::iterator mute_it = floater->mMuteDict.find((*it)->getUUID()); + if(mute_it != floater->mMuteDict.end() && LLMuteList::getInstance()->remove(mute_it->second)) + { + floater->mMuteDict.erase(mute_it); + removed = true; + } + } + + if (removed) { // Above removals may rebuild this dialog. - if (last_selected == floater->mMuteList->getItemCount()) { // we were on the last item, so select the last item again @@ -303,8 +362,12 @@ void LLFloaterMute::onClickRemove(void *data) // else select the item after the last item previously selected floater->mMuteList->selectNthItem(last_selected); } + floater->mMuteList->setNeedsSort(); + floater->mMuteList->updateSort(); + floater->updateButtons(); } - floater->updateButtons(); + + } //----------------------------------------------------------------------------- diff --git a/indra/newview/llfloatermute.h b/indra/newview/llfloatermute.h index 9034bf670..8abb6afdf 100644 --- a/indra/newview/llfloatermute.h +++ b/indra/newview/llfloatermute.h @@ -42,7 +42,8 @@ class LLButton; class LLLineEditor; class LLMessageSystem; class LLUUID; -class LLScrollListCtrl; +class LLNameListCtrl; +class LLMute; class LLFloaterMute : public LLFloater, public LLMuteListObserver, public LLFloaterSingleton @@ -74,7 +75,14 @@ private: static void callbackMuteByName(const std::string& text, void*); private: - LLScrollListCtrl* mMuteList; + LLNameListCtrl* mMuteList; + + LLPointer mAvatarIcon; //icon_avatar_offline.tga + LLPointer mObjectIcon; //inv_item_object.tga + LLPointer mGroupIcon; //icon_group.tga + LLPointer mNameIcon; //icon_name.tga + + std::map mMuteDict; //Easiest way to associate listitems with LLMute instances without hacking in, say, a hidden column. }; diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp index 3e279936f..0c8e7914e 100644 --- a/indra/newview/llfloaterproperties.cpp +++ b/indra/newview/llfloaterproperties.cpp @@ -537,11 +537,11 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) if (!is_link && is_obj_modify && can_agent_manipulate) { childSetEnabled("GroupLabel", true); - childSetEnabled("CheckGroupCopy",owner_mask & PERM_TRANSFER); + childSetEnabled("CheckGroupCopy", (owner_mask & (PERM_TRANSFER|PERM_COPY)) == (PERM_TRANSFER|PERM_COPY)); childSetEnabled("CheckGroupMod", owner_mask & PERM_MODIFY); childSetEnabled("CheckGroupMove", true); childSetEnabled("EveryoneLabel", true); - childSetEnabled("CheckEveryoneCopy",(owner_mask & PERM_COPY) && (owner_mask & PERM_TRANSFER)); + childSetEnabled("CheckEveryoneCopy", (owner_mask & (PERM_TRANSFER|PERM_COPY)) == (PERM_TRANSFER|PERM_COPY)); childSetEnabled("CheckEveryoneMove",true); } else @@ -551,7 +551,7 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item) childSetEnabled("CheckGroupMod", false); childSetEnabled("CheckGroupMove", false); childSetEnabled("EveryoneLabel", false); - childSetEnabled("CheckEveryoneCopy",FALSE); + childSetEnabled("CheckEveryoneCopy",false); childSetEnabled("CheckEveryoneMove",false); } diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 1219176d6..f52b0960c 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -277,6 +277,8 @@ BOOL LLFloaterTools::postBuild() mComboGridMode = getChild("combobox grid mode"); childSetCommitCallback("combobox grid mode",commit_grid_mode, this); + mCheckShowHighlight = getChild("checkbox show highlight"); + mCheckActualRoot = getChild("checkbox actual root"); // // Create Buttons // @@ -382,6 +384,8 @@ LLFloaterTools::LLFloaterTools() mCheckStretchUniform(NULL), mCheckStretchTexture(NULL), mCheckLimitDrag(NULL), + mCheckShowHighlight(NULL), + mCheckActualRoot(NULL), mBtnRotateLeft(NULL), mBtnRotateReset(NULL), @@ -712,6 +716,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask) if (mCheckStretchUniform) mCheckStretchUniform->setVisible( edit_visible ); if (mCheckStretchTexture) mCheckStretchTexture->setVisible( edit_visible ); if (mCheckLimitDrag) mCheckLimitDrag->setVisible( edit_visible ); + if (mCheckShowHighlight) mCheckShowHighlight->setVisible(edit_visible); + if (mCheckActualRoot) mCheckActualRoot->setVisible(edit_visible); // Create buttons BOOL create_visible = (tool == LLToolCompCreate::getInstance()); diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h index 085a2774e..90cdf83eb 100644 --- a/indra/newview/llfloatertools.h +++ b/indra/newview/llfloatertools.h @@ -143,6 +143,8 @@ public: LLCheckBoxCtrl* mCheckStretchUniform; LLCheckBoxCtrl* mCheckStretchTexture; LLCheckBoxCtrl* mCheckLimitDrag; + LLCheckBoxCtrl* mCheckShowHighlight; + LLCheckBoxCtrl* mCheckActualRoot; LLButton *mBtnRotateLeft; diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f21bb2902..0cd3906fb 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -899,12 +899,6 @@ void LLFloaterWorldMap::buildAvatarIDList() list->operateOnSelection(LLCtrlListInterface::OP_DELETE); } - LLSD default_column; - default_column["name"] = "friend name"; - default_column["label"] = "Friend Name"; - default_column["width"] = 500; - list->addColumn(default_column); - // Get all of the calling cards for avatar that are currently online LLCollectMappableBuddies collector; LLAvatarTracker::instance().applyFunctor(collector); diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h index 3bfbf3611..69060653f 100644 --- a/indra/newview/llfoldervieweventlistener.h +++ b/indra/newview/llfoldervieweventlistener.h @@ -77,7 +77,7 @@ public: virtual BOOL copyToClipboard() const = 0; virtual void cutToClipboard() = 0; virtual BOOL isClipboardPasteable() const = 0; - virtual void pasteFromClipboard() = 0; + virtual void pasteFromClipboard(bool only_copies = false) = 0; virtual void pasteLinkFromClipboard() = 0; virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0; virtual BOOL isUpToDate() const = 0; diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp index c89c414b5..3cde11774 100644 --- a/indra/newview/llgroupmgr.cpp +++ b/indra/newview/llgroupmgr.cpp @@ -36,6 +36,7 @@ #include #include +#include "llappviewer.h" //For gFrameCount #include "llagent.h" #include "llui.h" #include "message.h" @@ -44,6 +45,7 @@ #include "llstatusbar.h" #include "lleconomy.h" #include "llviewercontrol.h" +#include "llviewerregion.h" #include "llviewerwindow.h" #include "llfloaterdirectory.h" #include "llfloatergroupinfo.h" @@ -821,6 +823,7 @@ void LLGroupMgrGroupData::cancelRoleChanges() LLGroupMgr::LLGroupMgr() { + mLastGroupMembersRequestFrame = 0; } LLGroupMgr::~LLGroupMgr() @@ -1885,6 +1888,187 @@ void LLGroupMgr::sendGroupMemberEjects(const LLUUID& group_id, } } + +class AIHTTPTimeoutPolicy; +extern AIHTTPTimeoutPolicy groupMemberDataResponder_timeout; + +// Responder class for capability group management +class GroupMemberDataResponder : public LLHTTPClient::ResponderWithResult +{ +public: + virtual AIHTTPTimeoutPolicy const& getHTTPTimeoutPolicy(void) const { return groupMemberDataResponder_timeout; } + + GroupMemberDataResponder() {} + virtual ~GroupMemberDataResponder() {} + virtual void result(const LLSD& pContent); + virtual void error(U32 pStatus, const std::string& pReason); +private: + LLSD mMemberData; +}; + +void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason) +{ + LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL; +} + +void GroupMemberDataResponder::result(const LLSD& content) +{ + LLGroupMgr::processCapGroupMembersRequest(content); +} + + +// static +void LLGroupMgr::sendCapGroupMembersRequest(const LLUUID& group_id) +{ + // Have we requested the information already this frame? + if (mLastGroupMembersRequestFrame == gFrameCount) + return; + + LLViewerRegion* currentRegion = gAgent.getRegion(); + // Thank you FS:Ansariel! + if (!currentRegion) + { + LL_WARNS("GrpMgr") << "Agent does not have a current region. Uh-oh!" << LL_ENDL; + return; + } + + // Check to make sure we have our capabilities + if (!currentRegion->capabilitiesReceived()) + { + LL_WARNS("GrpMgr") << " Capabilities not received!" << LL_ENDL; + return; + } + + // Get our capability + std::string cap_url = currentRegion->getCapability("GroupMemberData"); + + // Thank you FS:Ansariel! + if (cap_url.empty()) + { + LL_INFOS("GrpMgr") << "Region has no GroupMemberData capability. Falling back to UDP fetch." << LL_ENDL; + sendGroupMembersRequest(group_id); + return; + } + + // Post to our service. Add a body containing the group_id. + LLSD body = LLSD::emptyMap(); + body["group_id"] = group_id; + + LLHTTPClient::ResponderPtr grp_data_responder = new GroupMemberDataResponder(); + + // This could take a while to finish, timeout after 5 minutes. + LLHTTPClient::post(cap_url, body, grp_data_responder); + + mLastGroupMembersRequestFrame = gFrameCount; +} + +// static +void LLGroupMgr::processCapGroupMembersRequest(const LLSD& content) +{ + // Did we get anything in content? + if (!content.size()) + { + LL_DEBUGS("GrpMgr") << "No group member data received." << LL_ENDL; + return; + } + + // If we have no members, there's no reason to do anything else + S32 num_members = content["member_count"]; + if (num_members < 1) + return; + + LLUUID group_id = content["group_id"].asUUID(); + + LLGroupMgrGroupData* group_datap = LLGroupMgr::getInstance()->getGroupData(group_id); + if (!group_datap) + { + LL_WARNS("GrpMgr") << "Received incorrect, possibly stale, group or request id" << LL_ENDL; + return; + } + + group_datap->mMemberCount = num_members; + + LLSD member_list = content["members"]; + LLSD titles = content["titles"]; + LLSD defaults = content["defaults"]; + + std::string online_status; + std::string title; + S32 contribution; + U64 member_powers; + // If this is changed to a bool, make sure to change the LLGroupMemberData constructor + BOOL is_owner; + + // Compute this once, rather than every time. + U64 default_powers = llstrtou64(defaults["default_powers"].asString().c_str(), NULL, 16); + + LLSD::map_const_iterator member_iter_start = member_list.beginMap(); + LLSD::map_const_iterator member_iter_end = member_list.endMap(); + for ( ; member_iter_start != member_iter_end; ++member_iter_start) + { + // Reset defaults + online_status = "unknown"; + title = titles[0].asString(); + contribution = 0; + member_powers = default_powers; + is_owner = false; + + const LLUUID member_id(member_iter_start->first); + LLSD member_info = member_iter_start->second; + + if (member_info.has("last_login")) + { + online_status = member_info["last_login"].asString(); + if (online_status == "Online") + online_status = LLTrans::getString("group_member_status_online"); + else + formatDateString(online_status); + } + + if (member_info.has("title")) + title = titles[member_info["title"].asInteger()].asString(); + + if (member_info.has("powers")) + member_powers = llstrtou64(member_info["powers"].asString().c_str(), NULL, 16); + + if (member_info.has("donated_square_meters")) + contribution = member_info["donated_square_meters"]; + + if (member_info.has("owner")) + is_owner = true; + + LLGroupMemberData* data = new LLGroupMemberData(member_id, + contribution, + member_powers, + title, + online_status, + is_owner); + + group_datap->mMembers[member_id] = data; + } + + // Technically, we have this data, but to prevent completely overhauling + // this entire system (it would be nice, but I don't have the time), + // I'm going to be dumb and just call services I most likely don't need + // with the thought being that the system might need it to be done. + // + // TODO: Refactor to reduce multiple calls for data we already have. + if (group_datap->mTitles.size() < 1) + LLGroupMgr::getInstance()->sendGroupTitlesRequest(group_id); + + group_datap->mMemberDataComplete = TRUE; + group_datap->mMemberRequestID.setNull(); + // Make the role-member data request + if (group_datap->mPendingRoleMemberRequest) + { + group_datap->mPendingRoleMemberRequest = FALSE; + LLGroupMgr::getInstance()->sendGroupRoleMembersRequest(group_id); + } + + group_datap->mChanged = TRUE; + LLGroupMgr::getInstance()->notifyObservers(GC_MEMBER_DATA); +} + void LLGroupMgr::sendGroupRoleChanges(const LLUUID& group_id) { lldebugs << "LLGroupMgr::sendGroupRoleChanges" << llendl; diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h index 225db1735..6a18add68 100644 --- a/indra/newview/llgroupmgr.h +++ b/indra/newview/llgroupmgr.h @@ -335,6 +335,9 @@ public: static void sendGroupMemberEjects(const LLUUID& group_id, uuid_vec_t& member_ids); + void sendCapGroupMembersRequest(const LLUUID& group_id); + static void processCapGroupMembersRequest(const LLSD& content); + void cancelGroupRoleChanges(const LLUUID& group_id); static void processGroupPropertiesReply(LLMessageSystem* msg, void** data); @@ -370,6 +373,8 @@ private: typedef std::set observer_set_t; typedef std::map observer_map_t; observer_map_t mParticularObservers; + + S32 mLastGroupMembersRequestFrame; }; diff --git a/indra/newview/llhoverview.cpp b/indra/newview/llhoverview.cpp index f6cff6f16..fa922a94b 100644 --- a/indra/newview/llhoverview.cpp +++ b/indra/newview/llhoverview.cpp @@ -262,39 +262,16 @@ void LLHoverView::updateText() else { // [/RLVa:KB] - - // [Ansariel: Display name support] - std::string complete_name = firstname->getString(); - complete_name += " "; - complete_name += lastname->getString(); - - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(hit_object->getID(), &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - complete_name = avatar_name.mDisplayName; - } - else - { - complete_name = avatar_name.getCompleteName(); - } - } - } - // [/Ansariel: Display name support] + std::string complete_name; + if (!LLAvatarNameCache::getPNSName(hit_object->getID(), complete_name)) + complete_name = firstname->getString() + std::string(" ") + lastname->getString(); if (title) { line.append(title->getString()); line.append(1, ' '); } - - // [Ansariel: Display name support] line += complete_name; - // [/Ansariel: Display name support] // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) } @@ -347,27 +324,13 @@ void LLHoverView::updateText() std::string name; if (!nodep->mPermissions->isGroupOwned()) { - // [Ansariel: Display name support] - LLAvatarName avatar_name; - // [/Ansariel: Display name support] owner = nodep->mPermissions->getOwner(); if (LLUUID::null == owner) { line.append(LLTrans::getString("TooltipPublic")); } - // [Ansariel: Display name support] - //else if(gCacheName->getFullName(owner, name)) - else if (LLAvatarNameCache::get(owner, &avatar_name)) + else if(LLAvatarNameCache::getPNSName(owner, name)) { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : name = avatar_name.getCompleteName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getCompleteName(); break; - } - // [/Ansariel: Display name support] // [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) { diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp index bd8ec64be..2cbe64c02 100644 --- a/indra/newview/llimpanel.cpp +++ b/indra/newview/llimpanel.cpp @@ -1297,27 +1297,23 @@ void LLFloaterIMPanel::init(const std::string& session_label) } } -// [Ansariel: Display name support] void LLFloaterIMPanel::lookupName() { LLAvatarNameCache::get(mOtherParticipantUUID, boost::bind(&LLFloaterIMPanel::onAvatarNameLookup, _1, _2, this)); } //static -void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data) +void LLFloaterIMPanel::onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data) { - LLFloaterIMPanel* self = (LLFloaterIMPanel*)user_data; + LLFloaterIMPanel* self = (LLFloaterIMPanel*)data; if (self && sFloaterIMPanels.count(self) != 0) { - std::string title = avatar_name.getCompleteName(); - if (!title.empty()) - { - self->setTitle(title); - } + std::string title; + LLAvatarNameCache::getPNSName(avatar_name, title); + self->setTitle(title); } } -// [/Ansariel: Display name support] LLFloaterIMPanel::~LLFloaterIMPanel() { @@ -1676,19 +1672,8 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, LLColor4 incol else { std::string show_name = name; - LLAvatarName avatar_name; - if (source.notNull() && - LLAvatarNameCache::get(source, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - switch (phoenix_name_system) - { - case 0 : show_name = avatar_name.getCompleteName(); break; - case 1 : show_name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : show_name = avatar_name.mDisplayName; break; - default : show_name = avatar_name.getCompleteName(); break; - } - } + if (source.notNull()) + LLAvatarNameCache::getPNSName(source, show_name); // Convert the name to a hotlink and add to message. const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source); mHistoryEditor->appendStyledText(show_name,false,prepend_newline,source_style); diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h index 943bd37c1..61d8c01f7 100644 --- a/indra/newview/llimpanel.h +++ b/indra/newview/llimpanel.h @@ -196,10 +196,8 @@ public: EInstantMessage dialog); virtual ~LLFloaterIMPanel(); - // [Ansariel: Display name support] void lookupName(); - static void onAvatarNameLookup(const LLUUID& id, const LLAvatarName& avatar_name, void* user_data); - // [/Ansariel: Display name support] + static void onAvatarNameLookup(const LLUUID&, const LLAvatarName& avatar_name, void* data); /*virtual*/ BOOL postBuild(); @@ -400,7 +398,6 @@ private: typedef std::map styleMap; static styleMap mStyleMap; - // [Ansariel: Display name support] static std::set sFloaterIMPanels; }; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 84e1d1199..a690f9c7b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -612,6 +612,48 @@ BOOL LLInvFVBridge::isClipboardPasteable() const return TRUE; } +bool LLInvFVBridge::isClipboardPasteableAsCopy() const +{ + // In cut mode, we don't paste copies. + if (LLInventoryClipboard::instance().isCutMode()) + { + return false; + } + + LLInventoryModel* model = getInventoryModel(); + if (!model) + { + return false; + } + + // In copy mode, we need to check each element of the clipboard to know if it's a link + LLInventoryPanel* panel = dynamic_cast(mInventoryPanel.get()); + LLDynamicArray objects; + LLInventoryClipboard::instance().retrieve(objects); + const S32 count = objects.count(); + for(S32 i = 0; i < count; i++) + { + const LLUUID &item_id = objects.get(i); + + // Folders may be links + const LLInventoryCategory *cat = model->getCategory(item_id); + if (cat) + { + const LLFolderBridge cat_br(panel, mRoot, item_id); + if (cat_br.isLink()) + return true; + // Skip to the next item in the clipboard + continue; + } + + // May be link item + const LLItemBridge item_br(panel, mRoot, item_id); + if (item_br.isLink()) + return true; + } + return false; +} + BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { if (!InventoryLinksEnabled()) @@ -731,6 +773,20 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { if (obj->getIsLinkType()) { + // Patch: Inventory-Links tweak, Can copy and cut Inventory Links + items.push_back(std::string("Copy Separator")); + + items.push_back(std::string("Copy")); + if (!isItemCopyable()) + { + disabled_items.push_back(std::string("Copy")); + } + + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } items.push_back(std::string("Find Original")); if (isLinkedObjectMissing()) { @@ -798,17 +854,26 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, } } + bool paste_as_copy = false; // If Paste As Copy is on the menu, Paste As Link will always show up disabled, so don't bother. // Don't allow items to be pasted directly into the COF or the inbox/outbox if (!isCOFFolder() && !isInboxFolder() && !isOutboxFolder()) { items.push_back(std::string("Paste")); + // Paste as copy if we have links. + if (InventoryLinksEnabled() && isClipboardPasteableAsCopy()) + { + items.push_back(std::string("Paste As Copy")); + paste_as_copy = true; + } } if (!isClipboardPasteable() || ((flags & FIRST_SELECTED_ITEM) == 0)) { disabled_items.push_back(std::string("Paste")); + disabled_items.push_back(std::string("Paste As Copy")); + paste_as_copy = false; } - if(InventoryLinksEnabled()) + if (!paste_as_copy && InventoryLinksEnabled()) { items.push_back(std::string("Paste As Link")); if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) @@ -1469,6 +1534,18 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action) folder_view_itemp->getListener()->pasteFromClipboard(); return; } + else if ("paste_copies" == action) + { + // Single item only + LLInventoryItem* itemp = model->getItem(mUUID); + if (!itemp) return; + + LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID()); + if (!folder_view_itemp) return; + + folder_view_itemp->getListener()->pasteFromClipboard(true); + return; + } else if ("paste_link" == action) { // Single item only @@ -1812,7 +1889,10 @@ BOOL LLItemBridge::removeItem() // we can't do this check because we may have items in a folder somewhere that is // not yet in memory, so we don't want false negatives. (If disabled, then we // know we only have links in the Outfits folder which we explicitly fetch.) - if (!InventoryLinksEnabled()) +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-06-01 (Catznip-2.2.0a) | Added: Catznip-2.0.1a + // Users move folders around and reuse links that way... if we know something has links then it's just bad not to warn them :| +// [/SL:KB] +// if (!InventoryLinksEnabled()) { if (!item->getIsLinkType()) { @@ -1873,13 +1953,26 @@ BOOL LLItemBridge::isItemCopyable() const return FALSE; }*/ - // You can never copy a link. - if (item->getIsLinkType()) +// // You can never copy a link. +// if (item->getIsLinkType()) +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + // We'll allow copying a link if: + // - its target is available + // - it doesn't point to another link [see LLViewerInventoryItem::getLinkedItem() which returns NULL in that case] + if (item->getIsLinkType() && !item->getLinkedItem()) +// [/SL:KB] { return FALSE; } - return item->getPermissions().allowCopyBy(gAgent.getID()) || InventoryLinksEnabled(); +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + // User can copy the item if: + // - the item (or its target in the case of a link) is "copy" + // - and/or if the item (or its target in the case of a link) has a linkable asset type + // NOTE: we do *not* want to return TRUE on everything like LL seems to do in SL-2.1.0 because not all types are "linkable" + return (item->getPermissions().allowCopyBy(gAgent.getID())) || (LLAssetType::lookupCanLink(item->getType())); +// [/SL:KB] +// return item->getPermissions().allowCopyBy(gAgent.getID()) || InventoryLinksEnabled(); } return FALSE; } @@ -2824,6 +2917,11 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action) pasteFromClipboard(); return; } + else if ("paste_copies" == action) + { + pasteFromClipboard(true); + return; + } else if ("paste_link" == action) { pasteLinkFromClipboard(); @@ -3062,7 +3160,7 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re return FALSE; } -void LLFolderBridge::pasteFromClipboard() +void LLFolderBridge::pasteFromClipboard(bool only_copies) { LLInventoryModel* model = getInventoryModel(); if(model && isClipboardPasteable()) @@ -3135,7 +3233,7 @@ void LLFolderBridge::pasteFromClipboard() dropToOutfit(item, move_is_into_current_outfit); } } - else if(LLInventoryClipboard::instance().isCutMode()) + else if (!only_copies && LLInventoryClipboard::instance().isCutMode()) { // Do a move to "paste" a "cut" // move_inventory_item() is not enough, as we have to update inventory locally too @@ -3160,6 +3258,11 @@ void LLFolderBridge::pasteFromClipboard() } else { + if (only_copies) + { + item = model->getLinkedItem(item_id); + obj = model->getObject(item->getUUID()); + } // Do a "copy" to "paste" a regular copy clipboard if (LLAssetType::AT_CATEGORY == obj->getType()) { @@ -3170,6 +3273,19 @@ void LLFolderBridge::pasteFromClipboard() copy_inventory_category(model, vicat, parent_id); } } +// [SL:KB] - Patch: Inventory-Links | Checked: 2010-04-12 (Catznip-2.2.0a) | Added: Catznip-2.0.0a + else if (!only_copies && LLAssetType::lookupIsLinkType(item->getActualType())) + { + link_inventory_item( + gAgent.getID(), + item->getLinkedUUID(), + parent_id, + item->getName(), + item->getDescription(), + item->getActualType(), + LLPointer(NULL)); + } +// [/SL:KB] else { copy_inventory_item( @@ -5231,9 +5347,10 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action) void LLObjectBridge::openItem() { + static LLCachedControl add(gSavedSettings, "LiruAddNotReplace"); // object double-click action is to wear/unwear object performAction(getInventoryModel(), - get_is_item_worn(mUUID) ? "detach" : "attach"); + get_is_item_worn(mUUID) ? "detach" : (add ? "wear_add" : "attach")); } std::string LLObjectBridge::getLabelSuffix() const @@ -6687,10 +6804,14 @@ void LLWearableBridgeAction::wearOnAvatar() { // TODO: investigate wearables may not be loaded at this point EXT-8231 + static LLCachedControl add(gSavedSettings, "LiruAddNotReplace"); LLViewerInventoryItem* item = getItem(); if(item) { - LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true); + if (get_is_item_worn(item)) + LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID()); + else + LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, !add); } } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 945c653ba..c5e26b752 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -108,8 +108,9 @@ public: virtual BOOL copyToClipboard() const; virtual void cutToClipboard(); virtual BOOL isClipboardPasteable() const; + bool isClipboardPasteableAsCopy() const; virtual BOOL isClipboardPasteableAsLink() const; - virtual void pasteFromClipboard() {} + virtual void pasteFromClipboard(bool only_copies = false) {} virtual void pasteLinkFromClipboard() {} void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, menuentry_vec_t &disabled_items, U32 flags); @@ -261,7 +262,7 @@ public: BOOL removeSystemFolder(); bool removeItemResponse(const LLSD& notification, const LLSD& response); - virtual void pasteFromClipboard(); + virtual void pasteFromClipboard(bool only_copies = false); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual BOOL hasChildren() const; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index c77312204..f9da070e2 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -74,8 +74,7 @@ static std::string getMarketplaceDomain() // SecondLife(tm) BETA grid. // Using the login URI is a bit of a kludge, but it's the best we've got at the moment. domain = utf8str_tolower(getLoginUriDomain()); // .lindenlab.com; ie, "aditi.lindenlab.com". - std::string::size_type len = domain.length(); - llassert(len > 14 && domain.substr(len - 14) == ".lindenlab.com"); + llassert(domain.length() > 14 && domain.substr(domain.length() - 14) == ".lindenlab.com"); if (domain == "damballah.lindenlab.com") { domain = "secondlife-staging.com"; diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp new file mode 100644 index 000000000..dd5f1ea68 --- /dev/null +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp @@ -0,0 +1,238 @@ +/** +* @file llmenuoptionpathfindingrebakenavmesh.cpp +* @brief Implementation of llmenuoptionpathfindingrebakenavmesh +* @author Prep@lindenlab.com +* +* $LicenseInfo:firstyear=2012&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2012, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + + +#include "llviewerprecompiledheaders.h" + +#include "llmenuoptionpathfindingrebakenavmesh.h" + +#include +#include + +#include "llagent.h" +#include "llenvmanager.h" +#include "llnotificationsutil.h" +#include "llpathfindingmanager.h" +#include "llpathfindingnavmesh.h" +#include "llpathfindingnavmeshstatus.h" +#include "llviewerregion.h" + +LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() + : LLSingleton(), + mIsInitialized(false), + mCanRebakeRegion(false), + mRebakeNavMeshMode(kRebakeNavMesh_Default), + mNavMeshSlot(), + mRegionCrossingSlot(), + mAgentStateSlot() +{ +} + +LLMenuOptionPathfindingRebakeNavmesh::~LLMenuOptionPathfindingRebakeNavmesh() +{ + if (mRebakeNavMeshMode == kRebakeNavMesh_RequestSent) + { + LL_WARNS("navmeshRebaking") << "During destruction of the LLMenuOptionPathfindingRebakeNavmesh " + << "singleton, the mode indicates that a request has been sent for which a response has yet " + << "to be received. This could contribute to a crash on exit." << LL_ENDL; + } + + llassert(!mIsInitialized); + if (mIsInitialized) + { + quit(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::initialize() +{ + llassert(!mIsInitialized); + if (!mIsInitialized) + { + mIsInitialized = true; + + setMode(kRebakeNavMesh_Default); + + createNavMeshStatusListenerForCurrentRegion(); + + if ( !mRegionCrossingSlot.connected() ) + { + mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); + } + + if (!mAgentStateSlot.connected()) + { + mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleAgentState, this, _1)); + } + LLPathfindingManager::getInstance()->requestGetAgentState(); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::quit() +{ + llassert(mIsInitialized); + if (mIsInitialized) + { + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + if (mRegionCrossingSlot.connected()) + { + mRegionCrossingSlot.disconnect(); + } + + if (mAgentStateSlot.connected()) + { + mAgentStateSlot.disconnect(); + } + + mIsInitialized = false; + } +} + +bool LLMenuOptionPathfindingRebakeNavmesh::canRebakeRegion() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the ability to rebake navmesh is being requested." << LL_ENDL; + } + return mCanRebakeRegion; +} + +LLMenuOptionPathfindingRebakeNavmesh::ERebakeNavMeshMode LLMenuOptionPathfindingRebakeNavmesh::getMode() const +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the mode is being requested." << LL_ENDL; + } + return mRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::sendRequestRebakeNavmesh() +{ + if (!mIsInitialized) + { + LL_ERRS("navmeshRebaking") << "LLMenuOptionPathfindingRebakeNavmesh class has not been initialized " + << "when the request is being made to rebake the navmesh." << LL_ENDL; + } + else + { + if (!canRebakeRegion()) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when user does not have permissions " + << "on this region" << LL_ENDL; + } + if (getMode() != kRebakeNavMesh_Available) + { + LL_WARNS("navmeshRebaking") << "attempting to rebake navmesh when mode is not available" + << LL_ENDL; + } + + setMode(kRebakeNavMesh_RequestSent); + LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) +{ + mRebakeNavMeshMode = pRebakeNavMeshMode; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) +{ + llassert(mIsInitialized); + mCanRebakeRegion = pCanRebakeRegion; +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) +{ + llassert(mIsInitialized); + if (getMode() == kRebakeNavMesh_RequestSent) + { + setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); + } + + if (!pResponseStatus) + { + LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); + } +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) +{ + llassert(mIsInitialized); + ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; + if (pNavMeshStatus.isValid()) + { + switch (pNavMeshStatus.getStatus()) + { + case LLPathfindingNavMeshStatus::kPending : + case LLPathfindingNavMeshStatus::kRepending : + rebakeNavMeshMode = kRebakeNavMesh_Available; + break; + case LLPathfindingNavMeshStatus::kBuilding : + rebakeNavMeshMode = kRebakeNavMesh_InProgress; + break; + case LLPathfindingNavMeshStatus::kComplete : + rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; + break; + default : + rebakeNavMeshMode = kRebakeNavMesh_Default; + llassert(0); + break; + } + } + + setMode(rebakeNavMeshMode); +} + +void LLMenuOptionPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() +{ + llassert(mIsInitialized); + createNavMeshStatusListenerForCurrentRegion(); + mCanRebakeRegion = FALSE; + LLPathfindingManager::getInstance()->requestGetAgentState(); +} + +void LLMenuOptionPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() +{ + if (mNavMeshSlot.connected()) + { + mNavMeshSlot.disconnect(); + } + + LLViewerRegion *currentRegion = gAgent.getRegion(); + if (currentRegion != NULL) + { + mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLMenuOptionPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); + LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); + } +} diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h similarity index 63% rename from indra/newview/llpanelpathfindingrebakenavmesh.h rename to indra/newview/llmenuoptionpathfindingrebakenavmesh.h index 5aa1c68d8..7b1d2873b 100644 --- a/indra/newview/llpanelpathfindingrebakenavmesh.h +++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h @@ -1,6 +1,6 @@ /** -* @file llpanelpathfindingrebakenavmesh.h -* @brief Header file for llpanelpathfindingrebakenavmesh +* @file llmenuoptionpathfindingrebakenavmesh.h +* @brief Header file for llmenuoptionpathfindingrebakenavmesh * @author Prep@lindenlab.com * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ @@ -24,34 +24,22 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -#ifndef LL_LLPANELPATHFINDINGREBAKENAVMESH_H -#define LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#ifndef LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H +#define LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H #include -#include "llpanel.h" #include "llpathfindingmanager.h" #include "llpathfindingnavmesh.h" +#include "llsingleton.h" -class LLButton; class LLPathfindingNavMeshStatus; -class LLPanelPathfindingRebakeNavmesh : public LLPanel +class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton { - - LOG_CLASS(LLPanelPathfindingRebakeNavmesh); + LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh); public: - static LLPanelPathfindingRebakeNavmesh* getInstance(); - - virtual BOOL postBuild(); - - virtual void draw(); - virtual BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen); - -protected: - -private: typedef enum { kRebakeNavMesh_Available, @@ -61,15 +49,21 @@ private: kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable } ERebakeNavMeshMode; - LLPanelPathfindingRebakeNavmesh(); - virtual ~LLPanelPathfindingRebakeNavmesh(); + LLMenuOptionPathfindingRebakeNavmesh(); + virtual ~LLMenuOptionPathfindingRebakeNavmesh(); - static LLPanelPathfindingRebakeNavmesh* getPanel(); + void initialize(); + void quit(); - void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); + bool canRebakeRegion() const; ERebakeNavMeshMode getMode() const; - void onNavMeshRebakeClick(); + void sendRequestRebakeNavmesh(); + +protected: + +private: + void setMode(ERebakeNavMeshMode pRebakeNavMeshMode); void handleAgentState(BOOL pCanRebakeRegion); void handleRebakeNavMeshResponse(bool pResponseStatus); @@ -78,19 +72,14 @@ private: void createNavMeshStatusListenerForCurrentRegion(); - bool doDraw() const; - void updatePosition(); + bool mIsInitialized; - BOOL mCanRebakeRegion; + bool mCanRebakeRegion; ERebakeNavMeshMode mRebakeNavMeshMode; - LLButton* mNavMeshRebakeButton; - LLButton* mNavMeshSendingButton; - LLButton* mNavMeshBakingButton; - LLPathfindingNavMesh::navmesh_slot_t mNavMeshSlot; boost::signals2::connection mRegionCrossingSlot; LLPathfindingManager::agent_state_slot_t mAgentStateSlot; }; -#endif // LL_LLPANELPATHFINDINGREBAKENAVMESH_H +#endif // LL_LLMENUOPTIONPATHFINDINGREBAKENAVMESH_H diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index f948b480b..724b15c94 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -629,37 +629,11 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec { msg.assign(""); std::string fullname; - if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname)) + if(mClosestAgentToCursor.notNull() && LLAvatarNameCache::getPNSName(mClosestAgentToCursor, fullname)) { //msg.append(fullname); // [RLVa:KB] - Version: 1.23.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b - // [Ansariel: Display name support] - // msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) ); - if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) - { - msg.append(RlvStrings::getAnonym(fullname)); - } - else - { - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(mClosestAgentToCursor, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - fullname = avatar_name.mDisplayName; - } - else - { - fullname = avatar_name.getCompleteName(true); - } - } - } - msg.append(fullname); - } - // [/Ansariel: Display name support] + msg.append( (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? fullname : RlvStrings::getAnonym(fullname) ); // [/RLVa:KB] msg.append("\n"); diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 5522f27a4..a834e7812 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -246,19 +246,23 @@ void LLOverlayBar::layoutButtons() if (state_buttons_panel->getVisible()) { - U32 required_width=0; + U32 button_count = 0; const child_list_t& view_list = *(state_buttons_panel->getChildList()); BOOST_FOREACH(LLView* viewp, view_list) { - required_width+=viewp->getRect().getWidth(); + if(!viewp->getEnabled()) + continue; + ++button_count; } + const S32 MAX_BAR_WIDTH = 600; + S32 bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH); - const S32 MAX_BAR_WIDTH = 800; - //const S32 MAX_BUTTON_WIDTH = 150; + // calculate button widths + const S32 MAX_BUTTON_WIDTH = 150; static LLCachedControl status_bar_pad("StatusBarPad",10); - S32 usable_bar_width = llclamp(state_buttons_panel->getRect().getWidth(), 0, MAX_BAR_WIDTH) - (view_list.size()-1) * status_bar_pad; - F32 element_scale = (F32)usable_bar_width / (F32)required_width; + S32 segment_width = llclamp(lltrunc((F32)(bar_width) / (F32)button_count), 0, MAX_BUTTON_WIDTH); + S32 btn_width = segment_width - status_bar_pad; // Evenly space all buttons, starting from left S32 left = 0; @@ -266,13 +270,14 @@ void LLOverlayBar::layoutButtons() BOOST_REVERSE_FOREACH(LLView* viewp, view_list) { + if(!viewp->getEnabled()) + continue; LLRect r = viewp->getRect(); - S32 new_width = r.getWidth() * element_scale; //if(dynamic_cast(viewp)) // new_width = llclamp(new_width,0,MAX_BUTTON_WIDTH); - r.setOriginAndSize(left, bottom, new_width, r.getHeight()); - viewp->setShape(r,false); - left += viewp->getRect().getWidth() + status_bar_pad; + r.setOriginAndSize(left, bottom, btn_width, r.getHeight()); + viewp->setRect(r); + left += segment_width; } } } diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp index 0ffd26e0f..904a809c9 100644 --- a/indra/newview/llpanelavatar.cpp +++ b/indra/newview/llpanelavatar.cpp @@ -89,6 +89,7 @@ #include +#include @@ -167,21 +168,9 @@ void LLPanelAvatarSecondLife::updatePartnerName() { if (mPartnerID.notNull()) { - // [Ansariel: Display name support] - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(mPartnerID, &avatar_name)) - { - std::string name; - switch (gSavedSettings.getS32("PhoenixNameSystem")) - { - case 0 : name = avatar_name.getLegacyName(); break; - case 1 : name = (avatar_name.mIsDisplayNameDefault ? avatar_name.mDisplayName : avatar_name.getCompleteName()); break; - case 2 : name = avatar_name.mDisplayName; break; - default : name = avatar_name.getLegacyName(); break; - } + std::string name; + if (LLAvatarNameCache::getPNSName(mPartnerID, name)) childSetTextArg("partner_edit", "[NAME]", name); - } - // [/Ansariel: Display name support] childSetEnabled("partner_info", TRUE); } } @@ -202,9 +191,7 @@ void LLPanelAvatarSecondLife::clearControls() childSetValue("born", ""); childSetValue("acct", ""); - // [Ansariel: Display name support] childSetTextArg("partner_edit", "[NAME]", LLStringUtil::null); - // [/Ansariel: Display name support] mPartnerID = LLUUID::null; @@ -283,23 +270,15 @@ void LLPanelAvatarSecondLife::processProperties(void* data, EAvatarProcessorType getChild("img")->setImageAssetID(pAvatarData->image_id); - //Chalice - Show avatar age in days. - int year, month, day; - sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); - time_t now = time(NULL); - struct tm * timeinfo; - timeinfo=localtime(&now); - timeinfo->tm_mon = --month; - timeinfo->tm_year = year - 1900; - timeinfo->tm_mday = day; - time_t birth = mktime(timeinfo); - std::stringstream NumberString; - NumberString << (difftime(now,birth) / (60*60*24)); - std::string born_on = pAvatarData->born_on; - born_on += " ("; - born_on += NumberString.str(); - born_on += ")"; - childSetValue("born", born_on); + // Show avatar age in days. + { + using namespace boost::gregorian; + int year, month, day; + sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year); + std::ostringstream born_on; + born_on << pAvatarData->born_on << " (" << day_clock::local_day() - date(year, month, day) << ")"; + childSetValue("born", born_on.str()); + } bool allow_publish = (pAvatarData->flags & AVATAR_ALLOW_PUBLISH); childSetValue("allow_publish", allow_publish); diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp index fbd323a09..097f0d8db 100644 --- a/indra/newview/llpanelgeneral.cpp +++ b/indra/newview/llpanelgeneral.cpp @@ -70,8 +70,10 @@ BOOL LLPanelGeneral::postBuild() childSetValue("show_my_name_checkbox", gSavedSettings.getBOOL("RenderNameHideSelf")); childSetValue("small_avatar_names_checkbox", gSavedSettings.getBOOL("SmallAvatarNames")); childSetValue("show_my_title_checkbox", gSavedSettings.getBOOL("RenderHideGroupTitle")); + childSetValue("away_when_idle_checkbox", gSavedSettings.getBOOL("AllowIdleAFK")); childSetValue("afk_timeout_spinner", gSavedSettings.getF32("AFKTimeout")); childSetValue("notify_money_change_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetValue("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("LiruNoTransactionClutter")); @@ -111,6 +113,12 @@ BOOL LLPanelGeneral::postBuild() childSetVisible("maturity_desired_combobox", can_choose); childSetVisible("maturity_desired_textbox", !can_choose); + childSetEnabled("afk_timeout_spinner", gSavedSettings.getBOOL("AllowIdleAFK")); + childSetCommitCallback("away_when_idle_checkbox", &onClickCheckbox, this); + + childSetEnabled("no_transaction_clutter_checkbox", gSavedSettings.getBOOL("NotifyMoneyChange")); + childSetCommitCallback("notify_money_change_checkbox", &onClickCheckbox, this); + childSetAction("clear_settings", &onClickClearSettings, this); return TRUE; @@ -145,8 +153,10 @@ void LLPanelGeneral::apply() gSavedSettings.setBOOL("RenderNameHideSelf", childGetValue("show_my_name_checkbox")); gSavedSettings.setBOOL("SmallAvatarNames", childGetValue("small_avatar_names_checkbox")); gSavedSettings.setBOOL("RenderHideGroupTitle", childGetValue("show_my_title_checkbox")); + gSavedSettings.setBOOL("AllowIdleAFK", childGetValue("away_when_idle_checkbox")); gSavedSettings.setF32("AFKTimeout", childGetValue("afk_timeout_spinner").asReal()); gSavedSettings.setBOOL("NotifyMoneyChange", childGetValue("notify_money_change_checkbox")); + gSavedSettings.setBOOL("LiruNoTransactionClutter", childGetValue("no_transaction_clutter_checkbox")); gSavedSettings.setF32("UIScaleFactor", childGetValue("ui_scale_slider").asReal()); @@ -163,6 +173,17 @@ void LLPanelGeneral::cancel() { } +// static +void LLPanelGeneral::onClickCheckbox(LLUICtrl* ctrl, void* data) +{ + LLPanelGeneral* self = (LLPanelGeneral*)data; + bool enabled = ctrl->getValue().asBoolean(); + if(ctrl->getName() == "away_when_idle_checkbox") + self->childSetEnabled("afk_timeout_spinner", enabled); + else if(ctrl->getName() == "notify_money_change_checkbox") + self->childSetEnabled("no_transaction_clutter_checkbox", enabled); +} + // static void LLPanelGeneral::onClickClearSettings(void*) { diff --git a/indra/newview/llpanelgeneral.h b/indra/newview/llpanelgeneral.h index 1249ec8ca..48c44b15c 100644 --- a/indra/newview/llpanelgeneral.h +++ b/indra/newview/llpanelgeneral.h @@ -47,6 +47,7 @@ public: void apply(); void cancel(); + static void onClickCheckbox(LLUICtrl* ctrl, void* data); static void onClickClearSettings(void*); static void callbackResetAllSettings(const LLSD& notification, const LLSD& response); }; diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 6f099f483..776f7fb9f 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -415,10 +415,9 @@ void LLPanelGroupGeneral::activate() LLGroupMgr::getInstance()->sendGroupTitlesRequest(mGroupID); LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mGroupID); - if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } mFirstUse = FALSE; @@ -884,7 +883,7 @@ void LLPanelGroupGeneral::updateMembers() for( ; mMemberProgress != gdatap->mMembers.end() && ifirst << ", " << iter->second->getTitle() << llendl; + lldebugs << "Adding " << mMemberProgress->first << ", " << mMemberProgress->second->getTitle() << llendl; LLGroupMemberData* member = mMemberProgress->second; if (!member) { @@ -924,15 +923,15 @@ void LLPanelGroupGeneral::updateMembers() } sAllTime += all_timer.getElapsedTimeF32(); - llinfos << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; + lldebugs << "Updated " << i << " of " << UPDATE_MEMBERS_PER_FRAME << "members in the list." << llendl; if (mMemberProgress == gdatap->mMembers.end()) { - llinfos << " member list completed." << llendl; + lldebugs << " member list completed." << llendl; mListVisibleMembers->setEnabled(TRUE); - llinfos << "All Time: " << sAllTime << llendl; - llinfos << "SD Time: " << sSDTime << llendl; - llinfos << "Element Time: " << sElementTime << llendl; + lldebugs << "All Time: " << sAllTime << llendl; + lldebugs << "SD Time: " << sSDTime << llendl; + lldebugs << "Element Time: " << sElementTime << llendl; } else { diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp index c9e765d7a..2f44a34bc 100644 --- a/indra/newview/llpanelgroupinvite.cpp +++ b/indra/newview/llpanelgroupinvite.cpp @@ -576,8 +576,8 @@ void LLPanelGroupInvite::updateLists() if (!mPendingUpdate) { LLGroupMgr::getInstance()->sendGroupPropertiesRequest(mImplementation->mGroupID); - LLGroupMgr::getInstance()->sendGroupMembersRequest(mImplementation->mGroupID); LLGroupMgr::getInstance()->sendGroupRoleDataRequest(mImplementation->mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mImplementation->mGroupID); } mPendingUpdate = TRUE; } diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp index 8ffae0c64..b7f09bd69 100644 --- a/indra/newview/llpanelgrouproles.cpp +++ b/indra/newview/llpanelgrouproles.cpp @@ -402,7 +402,7 @@ void LLPanelGroupRoles::activate() if (!gdatap || !gdatap->isMemberDataComplete() ) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } // Check role data. @@ -1979,7 +1979,7 @@ void LLPanelGroupRolesSubTab::update(LLGroupChange gc) if (!gdatap || !gdatap->isMemberDataComplete()) { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (!gdatap || !gdatap->isRoleMemberDataComplete()) @@ -2571,7 +2571,7 @@ void LLPanelGroupActionsSubTab::handleActionSelect() } else { - LLGroupMgr::getInstance()->sendGroupMembersRequest(mGroupID); + LLGroupMgr::getInstance()->sendCapGroupMembersRequest(mGroupID); } if (gdatap->isRoleDataComplete()) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 8929780d5..cd9d17587 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -131,7 +131,7 @@ public: virtual BOOL copyToClipboard() const; virtual void cutToClipboard(); virtual BOOL isClipboardPasteable() const; - virtual void pasteFromClipboard(); + virtual void pasteFromClipboard(bool only_copies = false); virtual void pasteLinkFromClipboard(); virtual void buildContextMenu(LLMenuGL& menu, U32 flags); virtual void performAction(LLInventoryModel* model, std::string action); @@ -604,7 +604,7 @@ BOOL LLTaskInvFVBridge::isClipboardPasteable() const return FALSE; } -void LLTaskInvFVBridge::pasteFromClipboard() +void LLTaskInvFVBridge::pasteFromClipboard(bool only_copies) { } diff --git a/indra/newview/llpanelpathfindingrebakenavmesh.cpp b/indra/newview/llpanelpathfindingrebakenavmesh.cpp deleted file mode 100644 index ca4bcfb67..000000000 --- a/indra/newview/llpanelpathfindingrebakenavmesh.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/** -* @file llpanelpathfindingrebakenavmesh.cpp -* @brief Implementation of llpanelpathfindingrebakenavmesh -* @author Prep@lindenlab.com -* -* $LicenseInfo:firstyear=2012&license=viewerlgpl$ -* Second Life Viewer Source Code -* Copyright (C) 2012, Linden Research, Inc. -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; -* version 2.1 of the License only. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -* -* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA -* $/LicenseInfo$ -*/ - - -#include "llviewerprecompiledheaders.h" - -#include "llpanelpathfindingrebakenavmesh.h" - -#include -#include - -#include "llagent.h" -#include "llbutton.h" -#include "llenvmanager.h" -#include "llnotificationsutil.h" -#include "llpanel.h" -#include "llpathfindingmanager.h" -#include "llpathfindingnavmesh.h" -#include "llpathfindingnavmeshstatus.h" -#include "lltoolbar.h" -#include "llviewerregion.h" -#include "llviewerwindow.h" -#include "lluictrlfactory.h" - - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getInstance() -{ - static LLPanelPathfindingRebakeNavmesh* panel = getPanel(); - return panel; -} - -BOOL LLPanelPathfindingRebakeNavmesh::postBuild() -{ - //Rebake button - mNavMeshRebakeButton = getChild("navmesh_btn"); - llassert(mNavMeshRebakeButton != NULL); - mNavMeshRebakeButton->setCommitCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick, this)); - //LLHints::registerHintTarget("navmesh_btn", mNavMeshRebakeButton->getHandle()); - - //Sending rebake request - mNavMeshSendingButton = findChild("navmesh_btn_sending"); - llassert(mNavMeshSendingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_sending", mNavMeshSendingButton->getHandle()); - - //rebaking... - mNavMeshBakingButton = findChild("navmesh_btn_baking"); - llassert(mNavMeshBakingButton != NULL); - //LLHints::registerHintTarget("navmesh_btn_baking", mNavMeshBakingButton->getHandle()); - - setMode(kRebakeNavMesh_Default); - - createNavMeshStatusListenerForCurrentRegion(); - - if ( !mRegionCrossingSlot.connected() ) - { - mRegionCrossingSlot = LLEnvManagerNew::getInstance()->setRegionChangeCallback(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed, this)); - } - - if (!mAgentStateSlot.connected()) - { - mAgentStateSlot = LLPathfindingManager::getInstance()->registerAgentStateListener(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleAgentState, this, _1)); - } - LLPathfindingManager::getInstance()->requestGetAgentState(); - - return LLPanel::postBuild(); -} - -void LLPanelPathfindingRebakeNavmesh::draw() -{ - if (doDraw()) - { - updatePosition(); - LLPanel::draw(); - } -} - -BOOL LLPanelPathfindingRebakeNavmesh::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sticky_rect_screen) -{ - gViewerWindow->unblockToolTips(); - - if (mNavMeshRebakeButton->getVisible()) - { - msg=mNavMeshRebakeButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshRebakeButton->getToolTip()); - } - else if (mNavMeshSendingButton->getVisible()) - { - msg=mNavMeshSendingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshSendingButton->getToolTip()); - } - else if (mNavMeshBakingButton->getVisible()) - { - msg=mNavMeshBakingButton->getToolTip(); - //LLToolTipMgr::instance().show(mNavMeshBakingButton->getToolTip()); - } - - // Convert rect local to screen coordinates - localPointToScreen( - 0, 0, - &(sticky_rect_screen->mLeft), &(sticky_rect_screen->mBottom) ); - localPointToScreen( - getRect().getWidth(), getRect().getHeight(), - &(sticky_rect_screen->mRight), &(sticky_rect_screen->mTop) ); - return true;//LLPanel::handleToolTip(x, y, mask); -} - -LLPanelPathfindingRebakeNavmesh::LLPanelPathfindingRebakeNavmesh() - : LLPanel(), - mCanRebakeRegion(FALSE), - mRebakeNavMeshMode(kRebakeNavMesh_Default), - mNavMeshRebakeButton(NULL), - mNavMeshSendingButton(NULL), - mNavMeshBakingButton(NULL), - mNavMeshSlot(), - mRegionCrossingSlot(), - mAgentStateSlot() -{ - // make sure we have the only instance of this class - static bool b = true; - llassert_always(b); - b=false; -} - -LLPanelPathfindingRebakeNavmesh::~LLPanelPathfindingRebakeNavmesh() -{ -} - -LLPanelPathfindingRebakeNavmesh* LLPanelPathfindingRebakeNavmesh::getPanel() -{ - LLPanelPathfindingRebakeNavmesh* panel = new LLPanelPathfindingRebakeNavmesh(); - LLUICtrlFactory::getInstance()->buildPanel(panel,"panel_navmesh_rebake.xml"); - return panel; -} - -void LLPanelPathfindingRebakeNavmesh::setMode(ERebakeNavMeshMode pRebakeNavMeshMode) -{ - if (pRebakeNavMeshMode == kRebakeNavMesh_Available) - { - LLNotificationsUtil::add("PathfindingRebakeNavmesh"); - } - mNavMeshRebakeButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_Available); - mNavMeshSendingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_RequestSent); - mNavMeshBakingButton->setVisible(pRebakeNavMeshMode == kRebakeNavMesh_InProgress); - mRebakeNavMeshMode = pRebakeNavMeshMode; -} - -LLPanelPathfindingRebakeNavmesh::ERebakeNavMeshMode LLPanelPathfindingRebakeNavmesh::getMode() const -{ - return mRebakeNavMeshMode; -} - -void LLPanelPathfindingRebakeNavmesh::onNavMeshRebakeClick() -{ - setMode(kRebakeNavMesh_RequestSent); - LLPathfindingManager::getInstance()->requestRebakeNavMesh(boost::bind(&LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse, this, _1)); -} - -void LLPanelPathfindingRebakeNavmesh::handleAgentState(BOOL pCanRebakeRegion) -{ - mCanRebakeRegion = pCanRebakeRegion; -} - -void LLPanelPathfindingRebakeNavmesh::handleRebakeNavMeshResponse(bool pResponseStatus) -{ - if (getMode() == kRebakeNavMesh_RequestSent) - { - setMode(pResponseStatus ? kRebakeNavMesh_InProgress : kRebakeNavMesh_Default); - } - - if (!pResponseStatus) - { - LLNotificationsUtil::add("PathfindingCannotRebakeNavmesh"); - } -} - -void LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus(const LLPathfindingNavMeshStatus &pNavMeshStatus) -{ - ERebakeNavMeshMode rebakeNavMeshMode = kRebakeNavMesh_Default; - if (pNavMeshStatus.isValid()) - { - switch (pNavMeshStatus.getStatus()) - { - case LLPathfindingNavMeshStatus::kPending : - case LLPathfindingNavMeshStatus::kRepending : - rebakeNavMeshMode = kRebakeNavMesh_Available; - break; - case LLPathfindingNavMeshStatus::kBuilding : - rebakeNavMeshMode = kRebakeNavMesh_InProgress; - break; - case LLPathfindingNavMeshStatus::kComplete : - rebakeNavMeshMode = kRebakeNavMesh_NotAvailable; - break; - default : - rebakeNavMeshMode = kRebakeNavMesh_Default; - llassert(0); - break; - } - } - - setMode(rebakeNavMeshMode); -} - -void LLPanelPathfindingRebakeNavmesh::handleRegionBoundaryCrossed() -{ - createNavMeshStatusListenerForCurrentRegion(); - mCanRebakeRegion = FALSE; - LLPathfindingManager::getInstance()->requestGetAgentState(); -} - -void LLPanelPathfindingRebakeNavmesh::createNavMeshStatusListenerForCurrentRegion() -{ - if (mNavMeshSlot.connected()) - { - mNavMeshSlot.disconnect(); - } - - LLViewerRegion *currentRegion = gAgent.getRegion(); - if (currentRegion != NULL) - { - mNavMeshSlot = LLPathfindingManager::getInstance()->registerNavMeshListenerForRegion(currentRegion, boost::bind(&LLPanelPathfindingRebakeNavmesh::handleNavMeshStatus, this, _2)); - LLPathfindingManager::getInstance()->requestGetNavMeshForRegion(currentRegion, true); - } -} - -bool LLPanelPathfindingRebakeNavmesh::doDraw() const -{ - return (mCanRebakeRegion && (mRebakeNavMeshMode != kRebakeNavMesh_NotAvailable)); -} - -void LLPanelPathfindingRebakeNavmesh::updatePosition() -{ -#if 0 - S32 y_pos = 0; - S32 bottom_tb_center = 0; - - if (LLToolBar* toolbar_bottom = gToolBarView->getChild("toolbar_bottom")) - { - y_pos = toolbar_bottom->getRect().getHeight(); - bottom_tb_center = toolbar_bottom->getRect().getCenterX(); - } - - S32 left_tb_width = 0; - if (LLToolBar* toolbar_left = gToolBarView->getChild("toolbar_left")) - { - left_tb_width = toolbar_left->getRect().getWidth(); - } - - if(LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container")) - { - panel_ssf_container->setOrigin(0, y_pos); - } - - S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width + 113 /* width of stand/fly button *//* + 10 *//* margin */; - - /*setOrigin( x_pos, 0);*/ -#endif -} diff --git a/indra/newview/llpathfindinglinkset.cpp b/indra/newview/llpathfindinglinkset.cpp index fe4daabd8..50b76378f 100644 --- a/indra/newview/llpathfindinglinkset.cpp +++ b/indra/newview/llpathfindinglinkset.cpp @@ -39,6 +39,7 @@ #define LINKSET_MODIFIABLE_FIELD "modifiable" #define LINKSET_CATEGORY_FIELD "navmesh_category" #define LINKSET_CAN_BE_VOLUME "can_be_volume" +#define LINKSET_IS_SCRIPTED_FIELD "is_scripted" #define LINKSET_PHANTOM_FIELD "phantom" #define LINKSET_WALKABILITY_A_FIELD "A" #define LINKSET_WALKABILITY_B_FIELD "B" @@ -62,6 +63,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLSD& pTerrainData) mLandImpact(0U), mIsModifiable(FALSE), mCanBeVolume(FALSE), + mIsScripted(FALSE), + mHasIsScripted(TRUE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -77,6 +80,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const std::string &pUUID, const LLSD& mLandImpact(0U), mIsModifiable(TRUE), mCanBeVolume(TRUE), + mIsScripted(FALSE), + mHasIsScripted(FALSE), mLinksetUse(kUnknown), mWalkabilityCoefficientA(MIN_WALKABILITY_VALUE), mWalkabilityCoefficientB(MIN_WALKABILITY_VALUE), @@ -93,6 +98,8 @@ LLPathfindingLinkset::LLPathfindingLinkset(const LLPathfindingLinkset& pOther) mLandImpact(pOther.mLandImpact), mIsModifiable(pOther.mIsModifiable), mCanBeVolume(pOther.mCanBeVolume), + mIsScripted(pOther.mIsScripted), + mHasIsScripted(pOther.mHasIsScripted), mLinksetUse(pOther.mLinksetUse), mWalkabilityCoefficientA(pOther.mWalkabilityCoefficientA), mWalkabilityCoefficientB(pOther.mWalkabilityCoefficientB), @@ -113,6 +120,8 @@ LLPathfindingLinkset& LLPathfindingLinkset::operator =(const LLPathfindingLinkse mLandImpact = pOther.mLandImpact; mIsModifiable = pOther.mIsModifiable; mCanBeVolume = pOther.mCanBeVolume; + mIsScripted = pOther.mIsScripted; + mHasIsScripted = pOther.mHasIsScripted; mLinksetUse = pOther.mLinksetUse; mWalkabilityCoefficientA = pOther.mWalkabilityCoefficientA; mWalkabilityCoefficientB = pOther.mWalkabilityCoefficientB; @@ -140,6 +149,11 @@ bool LLPathfindingLinkset::isShowUnmodifiablePhantomWarning(ELinksetUse pLinkset return (!isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); } +bool LLPathfindingLinkset::isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const +{ + return (isModifiable() && (isPhantom() != isPhantom(pLinksetUse))); +} + bool LLPathfindingLinkset::isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const { return (!canBeVolume() && ((pLinksetUse == kMaterialVolume) || (pLinksetUse == kExclusionVolume))); @@ -193,6 +207,13 @@ void LLPathfindingLinkset::parseLinksetData(const LLSD &pLinksetData) llassert(pLinksetData.has(LINKSET_MODIFIABLE_FIELD)); llassert(pLinksetData.get(LINKSET_MODIFIABLE_FIELD).isBoolean()); mIsModifiable = pLinksetData.get(LINKSET_MODIFIABLE_FIELD).asBoolean(); + + mHasIsScripted = pLinksetData.has(LINKSET_IS_SCRIPTED_FIELD); + if (mHasIsScripted) + { + llassert(pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).isBoolean()); + mIsScripted = pLinksetData.get(LINKSET_IS_SCRIPTED_FIELD).asBoolean(); + } } void LLPathfindingLinkset::parsePathfindingData(const LLSD &pLinksetData) diff --git a/indra/newview/llpathfindinglinkset.h b/indra/newview/llpathfindinglinkset.h index 73b4d6bad..308a3a1e0 100644 --- a/indra/newview/llpathfindinglinkset.h +++ b/indra/newview/llpathfindinglinkset.h @@ -63,12 +63,16 @@ public: inline ELinksetUse getLinksetUse() const {return mLinksetUse;}; + inline BOOL isScripted() const {return mIsScripted;}; + inline BOOL hasIsScripted() const {return mHasIsScripted;}; + inline S32 getWalkabilityCoefficientA() const {return mWalkabilityCoefficientA;}; inline S32 getWalkabilityCoefficientB() const {return mWalkabilityCoefficientB;}; inline S32 getWalkabilityCoefficientC() const {return mWalkabilityCoefficientC;}; inline S32 getWalkabilityCoefficientD() const {return mWalkabilityCoefficientD;}; bool isShowUnmodifiablePhantomWarning(ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(ELinksetUse pLinksetUse) const; LLSD encodeAlteredFields(ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; @@ -98,6 +102,8 @@ private: U32 mLandImpact; BOOL mIsModifiable; BOOL mCanBeVolume; + BOOL mIsScripted; + BOOL mHasIsScripted; ELinksetUse mLinksetUse; S32 mWalkabilityCoefficientA; S32 mWalkabilityCoefficientB; diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp index 746fa342a..b886e4676 100644 --- a/indra/newview/llpathfindinglinksetlist.cpp +++ b/indra/newview/llpathfindinglinksetlist.cpp @@ -113,6 +113,20 @@ bool LLPathfindingLinksetList::isShowUnmodifiablePhantomWarning(LLPathfindingLin return isShowWarning; } +bool LLPathfindingLinksetList::isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const +{ + bool isShowWarning = false; + + for (const_iterator objectIter = begin(); !isShowWarning && (objectIter != end()); ++objectIter) + { + const LLPathfindingObjectPtr objectPtr = objectIter->second; + const LLPathfindingLinkset *linkset = dynamic_cast(objectPtr.get()); + isShowWarning = linkset->isShowPhantomToggleWarning(pLinksetUse); + } + + return isShowWarning; +} + bool LLPathfindingLinksetList::isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const { bool isShowWarning = false; diff --git a/indra/newview/llpathfindinglinksetlist.h b/indra/newview/llpathfindinglinksetlist.h index 77c635864..1d38e4c11 100644 --- a/indra/newview/llpathfindinglinksetlist.h +++ b/indra/newview/llpathfindinglinksetlist.h @@ -43,6 +43,7 @@ public: LLSD encodeTerrainFields(LLPathfindingLinkset::ELinksetUse pLinksetUse, S32 pA, S32 pB, S32 pC, S32 pD) const; bool isShowUnmodifiablePhantomWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; + bool isShowPhantomToggleWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; bool isShowCannotBeVolumeWarning(LLPathfindingLinkset::ELinksetUse pLinksetUse) const; void determinePossibleStates(BOOL &pCanBeWalkable, BOOL &pCanBeStaticObstacle, BOOL &pCanBeDynamicObstacle, diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp index 916eceb4c..858d3203c 100644 --- a/indra/newview/llpathfindingobject.cpp +++ b/indra/newview/llpathfindingobject.cpp @@ -55,8 +55,10 @@ LLPathfindingObject::LLPathfindingObject() mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { } @@ -67,8 +69,10 @@ LLPathfindingObject::LLPathfindingObject(const std::string &pUUID, const LLSD &p mOwnerUUID(), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(false), - mLocation() + mLocation(), + mOwnerNameSignal() { parseObjectData(pObjectData); } @@ -80,14 +84,17 @@ LLPathfindingObject::LLPathfindingObject(const LLPathfindingObject& pOther) mOwnerUUID(pOther.mOwnerUUID), mHasOwnerName(false), mOwnerName(), + mAvatarNameCacheConnection(), mIsGroupOwned(pOther.mIsGroupOwned), - mLocation(pOther.mLocation) + mLocation(pOther.mLocation), + mOwnerNameSignal() { fetchOwnerName(); } LLPathfindingObject::~LLPathfindingObject() { + disconnectAvatarNameCacheConnection(); } LLPathfindingObject &LLPathfindingObject::operator =(const LLPathfindingObject& pOther) @@ -115,6 +122,23 @@ std::string LLPathfindingObject::getOwnerName() const return ownerName; } +LLPathfindingObject::name_connection_t LLPathfindingObject::registerOwnerNameListener(name_callback_t pOwnerNameCallback) +{ + llassert(hasOwner()); + + name_connection_t connection; + if (hasOwnerName()) + { + pOwnerNameCallback(this); + } + else + { + connection = mOwnerNameSignal.connect(pOwnerNameCallback); + } + + return connection; +} + void LLPathfindingObject::parseObjectData(const LLSD &pObjectData) { llassert(pObjectData.has(PATHFINDING_OBJECT_NAME_FIELD)); @@ -149,7 +173,7 @@ void LLPathfindingObject::fetchOwnerName() mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName); if (!mHasOwnerName) { - LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); + mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2)); } } } @@ -157,6 +181,19 @@ void LLPathfindingObject::fetchOwnerName() void LLPathfindingObject::handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName) { llassert(mOwnerUUID == pOwnerUUID); + mOwnerName = pAvatarName; mHasOwnerName = true; + + disconnectAvatarNameCacheConnection(); + + mOwnerNameSignal(this); +} + +void LLPathfindingObject::disconnectAvatarNameCacheConnection() +{ + if (mAvatarNameCacheConnection.connected()) + { + mAvatarNameCacheConnection.disconnect(); + } } diff --git a/indra/newview/llpathfindingobject.h b/indra/newview/llpathfindingobject.h index d45cc554f..b8d3ca236 100644 --- a/indra/newview/llpathfindingobject.h +++ b/indra/newview/llpathfindingobject.h @@ -30,8 +30,11 @@ #include #include +#include +#include #include "llavatarname.h" +#include "llavatarnamecache.h" #include "lluuid.h" #include "v3math.h" @@ -59,6 +62,12 @@ public: inline BOOL isGroupOwned() const {return mIsGroupOwned;}; inline const LLVector3& getLocation() const {return mLocation;}; + typedef boost::function name_callback_t; + typedef boost::signals2::signal name_signal_t; + typedef boost::signals2::connection name_connection_t; + + name_connection_t registerOwnerNameListener(name_callback_t pOwnerNameCallback); + protected: private: @@ -66,15 +75,18 @@ private: void fetchOwnerName(); void handleAvatarNameFetch(const LLUUID &pOwnerUUID, const LLAvatarName &pAvatarName); + void disconnectAvatarNameCacheConnection(); - LLUUID mUUID; - std::string mName; - std::string mDescription; - LLUUID mOwnerUUID; - bool mHasOwnerName; - LLAvatarName mOwnerName; - BOOL mIsGroupOwned; - LLVector3 mLocation; + LLUUID mUUID; + std::string mName; + std::string mDescription; + LLUUID mOwnerUUID; + bool mHasOwnerName; + LLAvatarName mOwnerName; + LLAvatarNameCache::callback_connection_t mAvatarNameCacheConnection; + BOOL mIsGroupOwned; + LLVector3 mLocation; + name_signal_t mOwnerNameSignal; }; #endif // LL_LLPATHFINDINGOBJECT_H diff --git a/indra/newview/llpathfindingobjectlist.cpp b/indra/newview/llpathfindingobjectlist.cpp index 68a7e736e..f1ecb45fc 100644 --- a/indra/newview/llpathfindingobjectlist.cpp +++ b/indra/newview/llpathfindingobjectlist.cpp @@ -45,6 +45,7 @@ LLPathfindingObjectList::LLPathfindingObjectList() LLPathfindingObjectList::~LLPathfindingObjectList() { + clear(); } bool LLPathfindingObjectList::isEmpty() const @@ -52,6 +53,15 @@ bool LLPathfindingObjectList::isEmpty() const return mObjectMap.empty(); } +void LLPathfindingObjectList::clear() +{ + for (LLPathfindingObjectMap::iterator objectIter = mObjectMap.begin(); objectIter != mObjectMap.end(); ++objectIter) + { + objectIter->second.reset(); + } + mObjectMap.clear(); +} + void LLPathfindingObjectList::update(LLPathfindingObjectPtr pUpdateObjectPtr) { if (pUpdateObjectPtr != NULL) diff --git a/indra/newview/llpathfindingobjectlist.h b/indra/newview/llpathfindingobjectlist.h index 3ad8e8b09..61580582d 100644 --- a/indra/newview/llpathfindingobjectlist.h +++ b/indra/newview/llpathfindingobjectlist.h @@ -47,6 +47,8 @@ public: bool isEmpty() const; + void clear(); + void update(LLPathfindingObjectPtr pUpdateObjectPtr); void update(LLPathfindingObjectListPtr pUpdateObjectListPtr); @@ -56,7 +58,6 @@ public: const_iterator begin() const; const_iterator end() const; - protected: LLPathfindingObjectMap &getObjectMap(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index afc63690f..4a4b3863b 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -6430,7 +6430,7 @@ LLBBox LLSelectMgr::getBBoxOfSelection() const //----------------------------------------------------------------------------- BOOL LLSelectMgr::canUndo() const { - return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstMoveableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- @@ -6448,7 +6448,7 @@ void LLSelectMgr::undo() //----------------------------------------------------------------------------- BOOL LLSelectMgr::canRedo() const { - return const_cast(this)->mSelectedObjects->getFirstEditableObject() != NULL; // HACK: casting away constness - MG + return const_cast(this)->mSelectedObjects->getFirstMoveableObject() != NULL; // HACK: casting away constness - MG } //----------------------------------------------------------------------------- diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index f9af3a2a9..5ad86c388 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -725,11 +725,9 @@ void LLStatusBar::setHealth(S32 health) { if (mHealth > (health + gSavedSettings.getF32("UISndHealthReductionThreshold"))) { - LLVOAvatar *me; - - if ((me = gAgentAvatarp)) + if (isAgentAvatarValid()) { - if (me->getSex() == SEX_FEMALE) + if (gAgentAvatarp->getSex() == SEX_FEMALE) { make_ui_sound("UISndHealthReductionF"); } diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index 958f4f0e6..7df652c41 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -253,8 +253,11 @@ void audio_update_wind(bool force_update) // which is sufficient to completely turn off or turn on wind noise volume_delta = 1.f; } - // mute wind entirely when the user asked - if (gSavedSettings.getBOOL("MuteWind")) + + static LLCachedControl MuteWind("MuteWind"); + static LLCachedControl ContinueFlying("LiruContinueFlyingOnUnsit"); + // mute wind entirely when the user asked or when the user is seated, but flying + if (MuteWind || (ContinueFlying && gAgentAvatarp&& gAgentAvatarp->isSitting())) { // volume decreases by itself gAudiop->mMaxWindGain = 0.f; diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index a12753cfb..e8294fc8b 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -427,13 +427,22 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { + case LLAgent::TELEPORT_PENDING: + gTeleportDisplayTimer.reset(); + if(!hide_tp_screen) + gViewerWindow->setShowProgress(TRUE); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); + gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]); + gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]); + break; + case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); if(!hide_tp_screen) gViewerWindow->setShowProgress(TRUE); - gViewerWindow->setProgressPercent(0); + gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 9c1dea408..d4fc9c02c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -183,6 +183,7 @@ #include "llmenugl.h" #include "llmimetypes.h" #include "llmorphview.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmoveview.h" #include "llmutelist.h" #include "llnotify.h" @@ -5327,6 +5328,39 @@ class LLToolsEnablePathfindingView : public view_listener_t } }; +class LLToolsDoPathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL); + + if (hasPathfinding) + { + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh(); + } + + return hasPathfinding; + } +}; + +class LLToolsEnablePathfindingRebakeRegion : public view_listener_t +{ + bool handleEvent(LLPointer event, const LLSD& userdata) + { + bool returnValue = false; + + if (LLPathfindingManager::getInstance() != NULL) + { + LLMenuOptionPathfindingRebakeNavmesh *rebakeInstance = LLMenuOptionPathfindingRebakeNavmesh::getInstance(); + returnValue = (rebakeInstance->canRebakeRegion() && + (rebakeInstance->getMode() == LLMenuOptionPathfindingRebakeNavmesh::kRebakeNavMesh_Available)); + + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(returnValue); + return returnValue; + } +}; + // Round the position of all root objects to the grid class LLToolsSnapObjectXY : public view_listener_t { @@ -9511,7 +9545,8 @@ void initialize_menus() addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding"); addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView"); - + addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion"); + addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion"); /*addMenu(new LLToolsVisibleBuyObject(), "Tools.VisibleBuyObject"); addMenu(new LLToolsVisibleTakeObject(), "Tools.VisibleTakeObject");*/ diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 57510b4ac..c452c85ab 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -213,6 +213,7 @@ extern bool gShiftFrame; // function prototypes bool check_offer_throttle(const std::string& from_name, bool check_only); void callbackCacheEstateOwnerName(const LLUUID& id, const std::string& full_name, bool is_group); +static void process_money_balance_reply_extended(LLMessageSystem* msg); //inventory offer throttle globals LLFrameTimer gThrottleTimer; @@ -3633,29 +3634,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data) } } - - // [Ansariel/Henri: Display name support] if (chatter && chatter->isAvatar()) { - if (LLAvatarNameCache::useDisplayNames()) - { - LLAvatarName avatar_name; - if (LLAvatarNameCache::get(from_id, &avatar_name)) - { - static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - if (phoenix_name_system == 2 || (phoenix_name_system == 1 && avatar_name.mIsDisplayNameDefault)) - { - from_name = avatar_name.mDisplayName; - } - else - { - from_name = avatar_name.getCompleteName(); - } - } + if (LLAvatarNameCache::getPNSName(from_id, from_name)) chat.mFromName = from_name; - } } - // [/Ansariel/Henri: Display name support] BOOL visible_in_chat_bubble = FALSE; std::string verb; @@ -5402,7 +5385,10 @@ void process_avatar_sit_response(LLMessageSystem *mesgsys, void **user_data) gAgentCamera.setForceMouselook(force_mouselook); // Forcing turning off flying here to prevent flying after pressing "Stand" // to stand up from an object. See EXT-1655. - gAgent.setFlying(FALSE); + // Unless the user wants to. + static LLCachedControl ContinueFlying("LiruContinueFlyingOnUnsit"); + if (!ContinueFlying) + gAgent.setFlying(FALSE); LLViewerObject* object = gObjectList.findObject(sitObjectID); if (object) @@ -5706,20 +5692,20 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) gStatusBar->setLandCredit(credit); gStatusBar->setLandCommitted(committed); } - static std::deque recent; - if(!desc.empty() && gSavedSettings.getBOOL("NotifyMoneyChange") - && (std::find(recent.rbegin(), recent.rend(), tid) == recent.rend())) - { - // Make the user confirm the transaction, since they might - // have missed something during an event. - // *TODO:translate - LLSD args; - args["MESSAGE"] = desc; - LLNotificationsUtil::add("SystemMessage", args); - // Also send notification to chat -- MC - LLChat chat(desc); - LLFloaterChat::addChat(desc); + if (desc.empty() + || !gSavedSettings.getBOOL("NotifyMoneyChange")) + { + // ...nothing to display + return; + } + + // Suppress duplicate messages about the same transaction + static std::deque recent; + if (std::find(recent.rbegin(), recent.rend(), tid) != recent.rend()) + { + return; + } // Once the 'recent' container gets large enough, chop some // off the beginning. @@ -5732,20 +5718,247 @@ void process_money_balance_reply( LLMessageSystem* msg, void** ) } //LL_DEBUGS("Messaging") << "Pushing back transaction " << tid << LL_ENDL; recent.push_back(tid); + + if (msg->has("TransactionInfo")) + { + // ...message has extended info for localization + process_money_balance_reply_extended(msg); + } + else + { + // Only old dev grids will not supply the TransactionInfo block, + // so we can just use the hard-coded English string. + LLSD args; + args["MESSAGE"] = desc; + LLNotificationsUtil::add("SystemMessage", args); + + // Also send notification to chat -- MC + LLChat chat(desc); + LLFloaterChat::addChat(desc); } } -bool handle_special_notification_callback(const LLSD& notification, const LLSD& response) +static std::string reason_from_transaction_type(S32 transaction_type, + const std::string& item_desc) +{ + // *NOTE: The keys for the reason strings are unusual because + // an earlier version of the code used English language strings + // extracted from hard-coded server English descriptions. + // Keeping them so we don't have to re-localize them. + switch (transaction_type) + { + case TRANS_OBJECT_SALE: + { + LLStringUtil::format_map_t arg; + arg["ITEM"] = item_desc; + return LLTrans::getString("for item", arg); + } + case TRANS_LAND_SALE: + return LLTrans::getString("for a parcel of land"); + + case TRANS_LAND_PASS_SALE: + return LLTrans::getString("for a land access pass"); + + case TRANS_GROUP_LAND_DEED: + return LLTrans::getString("for deeding land"); + + case TRANS_GROUP_CREATE: + return LLTrans::getString("to create a group"); + + case TRANS_GROUP_JOIN: + return LLTrans::getString("to join a group"); + + case TRANS_UPLOAD_CHARGE: + return LLTrans::getString("to upload"); + + case TRANS_CLASSIFIED_CHARGE: + return LLTrans::getString("to publish a classified ad"); + + // These have no reason to display, but are expected and should not + // generate warnings + case TRANS_GIFT: + case TRANS_PAY_OBJECT: + case TRANS_OBJECT_PAYS: + return std::string(); + + default: + llwarns << "Unknown transaction type " + << transaction_type << llendl; + return std::string(); + } +} + +static void process_money_balance_reply_extended(LLMessageSystem* msg) +{ + // Added in server 1.40 and viewer 2.1, support for localization + // and agent ids for name lookup. + S32 transaction_type = 0; + LLUUID source_id; + BOOL is_source_group = false; + LLUUID dest_id; + BOOL is_dest_group = false; + S32 amount = 0; + std::string item_description; + BOOL success = false; + + msg->getS32("TransactionInfo", "TransactionType", transaction_type); + msg->getUUID("TransactionInfo", "SourceID", source_id); + msg->getBOOL("TransactionInfo", "IsSourceGroup", is_source_group); + msg->getUUID("TransactionInfo", "DestID", dest_id); + msg->getBOOL("TransactionInfo", "IsDestGroup", is_dest_group); + msg->getS32("TransactionInfo", "Amount", amount); + msg->getString("TransactionInfo", "ItemDescription", item_description); + msg->getBOOL("MoneyData", "TransactionSuccess", success); + LL_INFOS("Money") << "MoneyBalanceReply source " << source_id + << " dest " << dest_id + << " type " << transaction_type + << " item " << item_description << LL_ENDL; + + if (source_id.isNull() && dest_id.isNull()) + { + // this is a pure balance update, no notification required + return; + } + + std::string source_slurl; + if (is_source_group) + { + gCacheName->getGroupName(source_id, source_slurl); + } + else + { + LLAvatarNameCache::getPNSName(source_id, source_slurl); + } + + std::string dest_slurl; + if (is_dest_group) + { + gCacheName->getGroupName(dest_id, dest_slurl); + } + else + { + LLAvatarNameCache::getPNSName(dest_id, dest_slurl); + } + + std::string reason = + reason_from_transaction_type(transaction_type, item_description); + + LLStringUtil::format_map_t args; + args["REASON"] = reason; // could be empty + args["AMOUNT"] = llformat("%d", amount); + + // Need to delay until name looked up, so need to know whether or not + // is group + bool is_name_group = false; + LLUUID name_id; + std::string message; + static LLCachedControl no_transaction_clutter("LiruNoTransactionClutter", false); + std::string notification = no_transaction_clutter ? "Payment" : "SystemMessage"; + LLSD final_args; + LLSD payload; + + bool you_paid_someone = (source_id == gAgentID); + if (you_paid_someone) + { + args["NAME"] = dest_slurl; + is_name_group = is_dest_group; + name_id = dest_id; + if (!reason.empty()) + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars", args) : + LLTrans::getString("you_paid_failure_ldollars", args); + } + else + { + // transaction fee to the system, eg, to create a group + message = success ? LLTrans::getString("you_paid_ldollars_no_name", args) : + LLTrans::getString("you_paid_failure_ldollars_no_name", args); + } + } + else + { + if (dest_id.notNull()) + { + message = success ? LLTrans::getString("you_paid_ldollars_no_reason", args) : + LLTrans::getString("you_paid_failure_ldollars_no_reason", args); + } + else + { + // no target, no reason, you just paid money + message = success ? LLTrans::getString("you_paid_ldollars_no_info", args) : + LLTrans::getString("you_paid_failure_ldollars_no_info", args); + } + } + final_args["MESSAGE"] = message; + } + else + { + // ...someone paid you + args["NAME"] = source_slurl; + is_name_group = is_source_group; + name_id = source_id; + if (!reason.empty()) + { + message = LLTrans::getString("paid_you_ldollars", args); + } + else + { + message = LLTrans::getString("paid_you_ldollars_no_reason", args); + } + final_args["MESSAGE"] = message; + + // make notification loggable + payload["from_id"] = source_id; + } + + // Despite using SLURLs, wait until the name is available before + // showing the notification, otherwise the UI layout is strange and + // the user sees a "Loading..." message + if (is_name_group) + { + gCacheName->getGroup(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); + } + else + { + LLAvatarNameCache::get(name_id, + boost::bind(&LLNotificationsUtil::add, + notification, final_args, payload)); + } +} + +bool handle_prompt_for_maturity_level_change_callback(const LLSD& notification, const LLSD& response) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (0 == option) { // set the preference to the maturity of the region we're calling - int preferredMaturity = notification["payload"]["_region_access"].asInteger(); - gSavedSettings.setU32("PreferredMaturity", preferredMaturity); - gAgent.sendMaturityPreferenceToServer(preferredMaturity); + U8 preferredMaturity = static_cast(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast(preferredMaturity)); + } + + return false; +} +bool handle_prompt_for_maturity_level_change_and_reteleport_callback(const LLSD& notification, const LLSD& response) +{ + S32 option = LLNotificationsUtil::getSelectedOption(notification, response); + + if (0 == option) + { + // set the preference to the maturity of the region we're calling + U8 preferredMaturity = static_cast(notification["payload"]["_region_access"].asInteger()); + gSavedSettings.setU32("PreferredMaturity", static_cast(preferredMaturity)); + gAgent.setMaturityRatingChangeDuringTeleport(preferredMaturity); + gAgent.restartFailedTeleportRequest(); + } + else + { + gAgent.clearTeleportRequest(); } return false; @@ -5754,39 +5967,148 @@ bool handle_special_notification_callback(const LLSD& notification, const LLSD& // some of the server notifications need special handling. This is where we do that. bool handle_special_notification(std::string notificationID, LLSD& llsdBlock) { - int regionAccess = llsdBlock["_region_access"].asInteger(); - llsdBlock["REGIONMATURITY"] = LLViewerRegion::accessToString(regionAccess); - - // we're going to throw the LLSD in there in case anyone ever wants to use it - LLNotificationsUtil::add(notificationID+"_Notify", llsdBlock); + U8 regionAccess = static_cast(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; if (regionAccess == SIM_ACCESS_MATURE) { if (gAgent.isTeen()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; } } else if (regionAccess == SIM_ACCESS_ADULT) { if (!gAgent.isAdult()) { - LLNotificationsUtil::add(notificationID+"_KB", llsdBlock); - return true; + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; } else if (gAgent.prefersPG() || gAgent.prefersMature()) { - LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_special_notification_callback); - return true; + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + else if (LLStringUtil::compareStrings(notificationID, "RegionEntryAccessBlocked") == 0) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock); + returnValue = true; } } - return false; + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; +} + +// some of the server notifications need special handling. This is where we do that. +bool handle_teleport_access_blocked(LLSD& llsdBlock) +{ + std::string notificationID("TeleportEntryAccessBlocked"); + U8 regionAccess = static_cast(llsdBlock["_region_access"].asInteger()); + std::string regionMaturity = LLViewerRegion::accessToString(regionAccess); + LLStringUtil::toLower(regionMaturity); + llsdBlock["REGIONMATURITY"] = regionMaturity; + + bool returnValue = false; + LLNotificationPtr maturityLevelNotification; + std::string notifySuffix = "_Notify"; + if (regionAccess == SIM_ACCESS_MATURE) + { + if (gAgent.isTeen()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else if (regionAccess == SIM_ACCESS_ADULT) + { + if (!gAgent.isAdult()) + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_AdultsOnlyContent", llsdBlock); + returnValue = true; + + notifySuffix = "_NotifyAdultsOnly"; + } + else if (gAgent.prefersPG() || gAgent.prefersMature()) + { + if (gAgent.hasRestartableFailedTeleportRequest()) + { + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_ChangeAndReTeleport", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_and_reteleport_callback); + returnValue = true; + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_Change", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + else + { + gAgent.clearTeleportRequest(); + maturityLevelNotification = LLNotificationsUtil::add(notificationID+"_PreferencesOutOfSync", llsdBlock, llsdBlock, handle_prompt_for_maturity_level_change_callback); + returnValue = true; + } + } + + if ((maturityLevelNotification == NULL) || maturityLevelNotification->isIgnored()) + { + // Given a simple notification if no maturityLevelNotification is set or it is ignore + LLNotificationsUtil::add(notificationID + notifySuffix, llsdBlock); + } + + return returnValue; } bool attempt_standard_notification(LLMessageSystem* msgsystem) @@ -5830,16 +6152,20 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem) RegionEntryAccessBlocked RegionEntryAccessBlocked_Notify + RegionEntryAccessBlocked_NotifyAdultsOnly RegionEntryAccessBlocked_Change - RegionEntryAccessBlocked_KB + RegionEntryAccessBlocked_AdultsOnlyContent + RegionEntryAccessBlocked_ChangeAndReTeleport LandClaimAccessBlocked LandClaimAccessBlocked_Notify + LandClaimAccessBlocked_NotifyAdultsOnly LandClaimAccessBlocked_Change - LandClaimAccessBlocked_KB + LandClaimAccessBlocked_AdultsOnlyContent LandBuyAccessBlocked LandBuyAccessBlocked_Notify + LandBuyAccessBlocked_NotifyAdultsOnly LandBuyAccessBlocked_Change - LandBuyAccessBlocked_KB + LandBuyAccessBlocked_AdultsOnlyContent -----------------------------------------------------------------------*/ if (handle_special_notification(notificationID, llsdBlock)) @@ -5891,6 +6217,30 @@ void process_alert_message(LLMessageSystem *msgsystem, void **user_data) } } +bool handle_not_age_verified_alert(const std::string &pAlertName) +{ + LLNotificationPtr notification = LLNotificationsUtil::add(pAlertName); + if ((notification == NULL) || notification->isIgnored()) + { + LLNotificationsUtil::add(pAlertName + "_Notify"); + } + + return true; +} + +bool handle_special_alerts(const std::string &pAlertName) +{ + bool isHandled = false; + + if (LLStringUtil::compareStrings(pAlertName, "NotAgeVerified") == 0) + { + + isHandled = handle_not_age_verified_alert(pAlertName); + } + + return isHandled; +} + void process_alert_core(const std::string& message, BOOL modal) { // HACK -- handle callbacks for specific alerts @@ -5914,7 +6264,10 @@ void process_alert_core(const std::string& message, BOOL modal) // Allow the server to spawn a named alert so that server alerts can be // translated out of English. std::string alert_name(message.substr(ALERT_PREFIX.length())); - LLNotificationsUtil::add(alert_name); + if (!handle_special_alerts(alert_name)) + { + LLNotificationsUtil::add(alert_name); + } } else if (message.find(NOTIFY_PREFIX) == 0) { @@ -6215,6 +6568,7 @@ bool script_question_cb(const LLSD& notification, const LLSD& response) // ...with description on top LLNotificationsUtil::add("DebitPermissionDetails"); + return false; } // check whether permissions were granted or denied @@ -6583,7 +6937,7 @@ void process_teleport_failed(LLMessageSystem *msg, void**) else { // change notification name in this special case - if (handle_special_notification("RegionEntryAccessBlocked", llsd_block)) + if (handle_teleport_access_blocked(llsd_block)) { if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE ) { @@ -6652,8 +7006,9 @@ void process_teleport_local(LLMessageSystem *msg,void**) } } + static LLCachedControl fly_after_tp(gSavedSettings, "LiruFlyAfterTeleport"); // Sim tells us whether the new position is off the ground - if (teleport_flags & TELEPORT_FLAGS_IS_FLYING) + if (fly_after_tp || (teleport_flags & TELEPORT_FLAGS_IS_FLYING)) { gAgent.setFlying(TRUE); } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 01eb55b10..681cfd4fd 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -720,6 +720,31 @@ std::string LLViewerRegion::accessToShortString(U8 sim_access) } } +// static +U8 LLViewerRegion::shortStringToAccess(const std::string &sim_access) +{ + U8 accessValue; + + if (LLStringUtil::compareStrings(sim_access, "PG") == 0) + { + accessValue = SIM_ACCESS_PG; + } + else if (LLStringUtil::compareStrings(sim_access, "M") == 0) + { + accessValue = SIM_ACCESS_MATURE; + } + else if (LLStringUtil::compareStrings(sim_access, "A") == 0) + { + accessValue = SIM_ACCESS_ADULT; + } + else + { + accessValue = SIM_ACCESS_MIN; + } + + return accessValue; +} + // static void LLViewerRegion::processRegionInfo(LLMessageSystem* msg, void**) { @@ -1565,7 +1590,6 @@ void LLViewerRegion::unpackRegionHandshake() msg->sendReliable(host); } - void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) { capabilityNames.append("AgentState"); @@ -1576,11 +1600,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("CopyInventoryFromNotecard"); capabilityNames.append("CreateInventoryCategory"); capabilityNames.append("DispatchRegionInfo"); + capabilityNames.append("EnvironmentSettings"); capabilityNames.append("EstateChangeInfo"); capabilityNames.append("EventQueueGet"); - capabilityNames.append("EnvironmentSettings"); - /*capabilityNames.append("ObjectMedia"); - capabilityNames.append("ObjectMediaNavigate");*/ if (gSavedSettings.getBOOL("UseHTTPInventory")) //Caps suffixed with 2 by LL. Don't update until rest of fetch system is updated first. { @@ -1591,12 +1613,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) } capabilityNames.append("GetDisplayNames"); - capabilityNames.append("GetTexture"); capabilityNames.append("GetMesh"); capabilityNames.append("GetObjectCost"); capabilityNames.append("GetObjectPhysicsData"); + capabilityNames.append("GetTexture"); + capabilityNames.append("GroupMemberData"); capabilityNames.append("GroupProposalBallot"); - capabilityNames.append("HomeLocation"); //capabilityNames.append("LandResources"); //Script limits (llfloaterscriptlimits.cpp) capabilityNames.append("MapLayer"); @@ -1606,9 +1628,11 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) #endif //MESH_IMPORT capabilityNames.append("NavMeshGenerationStatus"); capabilityNames.append("NewFileAgentInventory"); + /*capabilityNames.append("ObjectMedia"); + capabilityNames.append("ObjectMediaNavigate");*/ capabilityNames.append("ObjectNavMeshProperties"); + capabilityNames.append("ParcelNavigateMedia"); //Singu Note: Removed by Baker, do we need this? capabilityNames.append("ParcelPropertiesUpdate"); - capabilityNames.append("ParcelNavigateMedia"); capabilityNames.append("ParcelVoiceInfoRequest"); capabilityNames.append("ProductInfoRequest"); capabilityNames.append("ProvisionVoiceAccountRequest"); @@ -1622,10 +1646,10 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("SendUserReport"); capabilityNames.append("SendUserReportWithScreenshot"); capabilityNames.append("ServerReleaseNotes"); - capabilityNames.append("SimConsole"); - capabilityNames.append("SimulatorFeatures"); capabilityNames.append("SetDisplayName"); + capabilityNames.append("SimConsole"); //Singu Note: Removed by Baker, sim console won't work without this. capabilityNames.append("SimConsoleAsync"); + capabilityNames.append("SimulatorFeatures"); capabilityNames.append("StartGroupProposal"); capabilityNames.append("TerrainNavMeshProperties"); capabilityNames.append("TextureStats"); @@ -1633,10 +1657,10 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateAgentInformation"); capabilityNames.append("UpdateAgentLanguage"); capabilityNames.append("UpdateGestureAgentInventory"); - capabilityNames.append("UpdateNotecardAgentInventory"); - capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateGestureTaskInventory"); + capabilityNames.append("UpdateNotecardAgentInventory"); capabilityNames.append("UpdateNotecardTaskInventory"); + capabilityNames.append("UpdateScriptAgent"); capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UploadBakedTexture"); //capabilityNames.append("ViewerMetrics"); @@ -1928,3 +1952,9 @@ bool LLViewerRegion::meshRezEnabled() const } } +bool LLViewerRegion::dynamicPathfindingEnabled() const +{ + return ( mSimulatorFeatures.has("DynamicPathfindingEnabled") && + mSimulatorFeatures["DynamicPathfindingEnabled"].asBoolean()); +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b7fd43602..3e5f1fd24 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -210,6 +210,7 @@ public: // Returns "M", "PG", "A" etc. static std::string accessToShortString(U8 sim_access); + static U8 shortStringToAccess(const std::string &sim_access); // Return access icon name static std::string getAccessIcon(U8 sim_access); @@ -293,6 +294,9 @@ public: void getSimulatorFeatures(LLSD& info); void setSimulatorFeatures(const LLSD& info); + + bool dynamicPathfindingEnabled() const; + typedef enum { CACHE_MISS_TYPE_FULL = 0, diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 0cd49f717..313673721 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -32,7 +32,6 @@ #include "llviewerprecompiledheaders.h" -#include //First, because glh_linear #defines equivalent.. which boost uses internally #include "llfeaturemanager.h" #include "llviewershadermgr.h" @@ -172,7 +171,8 @@ LLGLSLShader gPostNightVisionProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not LLGLSLShader gPostGaussianBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList LLGLSLShader gPostPosterizeProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList LLGLSLShader gPostMotionBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList - +LLGLSLShader gPostVignetteProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList + // Deferred rendering shaders LLGLSLShader gDeferredImpostorProgram(LLViewerShaderMgr::SHADER_DEFERRED); LLGLSLShader gDeferredWaterProgram(LLViewerShaderMgr::SHADER_DEFERRED); //calculatesAtmospherics @@ -307,18 +307,6 @@ void LLViewerShaderMgr::setShaders() return; } - { - const std::string dumpdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"shader_dump")+gDirUtilp->getDirDelimiter(); - try - { - boost::filesystem::remove_all(dumpdir); - } - catch(const boost::filesystem::filesystem_error& e) - { - llinfos << "boost::filesystem::remove_all(\""+dumpdir+"\") failed: '" + e.code().message() + "'" << llendl; - } - } - LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); static const LLCachedControl no_texture_indexing("ShyotlUseLegacyTextureBatching",false); if(no_texture_indexing) @@ -482,6 +470,12 @@ void LLViewerShaderMgr::setShaders() if (loaded) { loaded = loadTransformShaders(); + if(!loaded) //Failed to load. Just wipe all transformfeedback shaders and continue like nothing happened. + { + mVertexShaderLevel[SHADER_TRANSFORM] = 0; + unloadShaderClass(SHADER_TRANSFORM); + loaded = true; + } } if (loaded) @@ -908,7 +902,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects() shaderUniforms.push_back("contrast"); shaderUniforms.push_back("contrastBase"); shaderUniforms.push_back("saturation"); - shaderUniforms.push_back("lumWeights"); gPostColorFilterProgram.mName = "Color Filter Shader (Post)"; gPostColorFilterProgram.mShaderFiles.clear(); @@ -929,7 +922,6 @@ BOOL LLViewerShaderMgr::loadShadersEffects() shaderUniforms.reserve(3); shaderUniforms.push_back("brightMult"); shaderUniforms.push_back("noiseStrength"); - shaderUniforms.push_back("lumWeights"); gPostNightVisionProgram.mName = "Night Vision Shader (Post)"; gPostNightVisionProgram.mShaderFiles.clear(); @@ -998,6 +990,26 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostMotionBlurProgram.uniform1i("tex1", 1); } } + + { + vector shaderUniforms; + shaderUniforms.reserve(3); + shaderUniforms.push_back("vignette_darkness"); + shaderUniforms.push_back("vignette_radius"); + shaderUniforms.push_back("screen_res"); + + gPostVignetteProgram.mName = "Vignette Shader (Post)"; + gPostVignetteProgram.mShaderFiles.clear(); + gPostVignetteProgram.mShaderFiles.push_back(make_pair("effects/VignetteF.glsl", GL_FRAGMENT_SHADER_ARB)); + gPostVignetteProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB)); + gPostVignetteProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; + if(gPostVignetteProgram.createShader(NULL, &shaderUniforms)) + { + gPostVignetteProgram.bind(); + gPostVignetteProgram.uniform1i("tex0", 0); + } + } + #endif return success; @@ -1495,12 +1507,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { gDeferredStarProgram.mName = "Deferred Star Program"; + vector shaderUniforms(mWLUniforms); + shaderUniforms.push_back("custom_alpha"); gDeferredStarProgram.mShaderFiles.clear(); gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB)); gDeferredStarProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY; - success = gDeferredStarProgram.createShader(NULL, &mWLUniforms); + success = gDeferredStarProgram.createShader(NULL, &shaderUniforms); } if (success) diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index 6013a47f2..8a2667555 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -873,7 +873,7 @@ void send_stats() llinfos << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << llendl; llinfos << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << llendl; - body["DisplayNamesEnabled"] = gSavedSettings.getS32("PhoenixNameSystem") > 0; + body["DisplayNamesEnabled"] = gSavedSettings.getS32("PhoenixNameSystem") == 1 || gSavedSettings.getS32("PhoenixNameSystem") == 2; body["DisplayNamesShowUsername"] = gSavedSettings.getS32("PhoenixNameSystem") == 1; body["MinimalSkin"] = false; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 6e1c57fb3..a7d79e200 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -630,11 +630,13 @@ void LLViewerTextureList::updateImages(F32 max_time) //Can't check gTeleportDisplay due to a process_teleport_local(), which sets it to true for local teleports... so: // Do this case if IS teleporting but NOT local teleporting, AND either the TP screen is set to appear OR we just entered the sim (TELEPORT_START_ARRIVAL) - if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE && gAgent.getTeleportState() != LLAgent::TELEPORT_LOCAL && - (!hide_tp_screen || gAgent.getTeleportState() == LLAgent::TELEPORT_START_ARRIVAL)) + LLAgent::ETeleportState state = gAgent.getTeleportState(); + if(state != LLAgent::TELEPORT_NONE && state != LLAgent::TELEPORT_LOCAL && state != LLAgent::TELEPORT_PENDING && + (!hide_tp_screen || state == LLAgent::TELEPORT_START_ARRIVAL || state == LLAgent::TELEPORT_ARRIVING)) { if(!cleared) { + llinfos << "Flushing upon teleport." << llendl; clearFetchingRequests(); //gPipeline.clearRebuildGroups() really doesn't belong here... but since it is here, do a few other needed things too. gPipeline.clearRebuildGroups(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e0a0ded13..001722e8d 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -128,10 +128,10 @@ #include "llkeyboard.h" #include "lllineeditor.h" #include "llmenugl.h" +#include "llmenuoptionpathfindingrebakenavmesh.h" #include "llmodaldialog.h" #include "llmorphview.h" #include "llmoveview.h" -#include "llpanelpathfindingrebakenavmesh.h" #include "llnotify.h" #include "lloverlaybar.h" #include "llpreviewtexture.h" @@ -1959,10 +1959,11 @@ void LLViewerWindow::initWorldUI() // put behind everything else in the UI mRootView->addChildInBack(gHUDView); } - + LLPanel* panel_ssf_container = getRootView()->getChild("state_management_buttons_container"); - LLPanelPathfindingRebakeNavmesh *panel_rebake_navmesh = LLPanelPathfindingRebakeNavmesh::getInstance(); - panel_ssf_container->addChild(panel_rebake_navmesh); + panel_ssf_container->setVisible(TRUE); + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->initialize(); } // initWorldUI that wasn't before logging in. Some of this may require the access the 'LindenUserDir'. @@ -2041,6 +2042,9 @@ void LLViewerWindow::shutdownViews() // Delete all child views. delete mRootView; mRootView = NULL; + llinfos << "RootView deleted." << llendl ; + + LLMenuOptionPathfindingRebakeNavmesh::getInstance()->quit(); // Automatically deleted as children of mRootView. Fix the globals. gFloaterTools = NULL; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ade46261f..7787fb17b 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -3771,8 +3771,8 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name) static const LLCachedControl phoenix_name_system("PhoenixNameSystem", 0); - bool show_display_names = phoenix_name_system > 0; - bool show_usernames = phoenix_name_system < 2; + bool show_display_names = phoenix_name_system == 1 || phoenix_name_system == 2; + bool show_usernames = phoenix_name_system != 2; if (show_display_names && LLAvatarNameCache::useDisplayNames()) { LLAvatarName av_name; @@ -4372,7 +4372,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent) } LLVector3 velDir = getVelocity(); velDir.normalize(); - if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) + static LLCachedControl TurnAround("TurnAroundWhenWalkingBackwards"); + if (!TurnAround && (mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end())) { F32 vpD = velDir * primDir; if (vpD < -0.5f) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index c6df5951f..d3f199fdf 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1425,6 +1425,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons LLStrider normalsp; LLStrider texCoordsp; LLStrider indicesp; + LLStrider colorsp; S32 index_offset; LLFace *facep; @@ -1481,7 +1482,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons if (!facep->getVertexBuffer()) { facep->setSize(4, 6); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); //Singu Note: Using LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK on purpose. buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE); facep->setGeomIndex(0); facep->setIndicesIndex(0); @@ -1491,6 +1492,7 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons llassert(facep->getVertexBuffer()->getNumIndices() == 6); index_offset = facep->getGeometry(verticesp,normalsp,texCoordsp, indicesp); + facep->getColors(colorsp); if (-1 == index_offset) { @@ -1516,6 +1518,11 @@ BOOL LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, const S32 f, cons *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + *(colorsp++) = LLColor4::white; + facep->getVertexBuffer()->flush(); if (is_sun) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6b450d841..1620f16b3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -865,7 +865,7 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); - for (U32 i = 0; i < 3; i++) + for (U32 i = 0; i < 2; i++) { mGlow[i].release(); } @@ -931,16 +931,26 @@ void LLPipeline::createGLBuffers() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (LLPipeline::sRenderGlow) { //screen space glow buffers const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); - for (U32 i = 0; i < 3; i++) + glClearColor(0,0,0,0); + gGL.setColorMask(true, true); + for (U32 i = 0; i < 2; i++) { - mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); + if(mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE)) + { + mGlow[i].bindTarget(); + mGlow[i].clear(); + mGlow[i].unbindTarget(); + } } + allocateScreenBuffer(resX,resY); } @@ -6517,8 +6527,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); - mGlow[2].bindTarget(); - mGlow[2].clear(); + mGlow[1].bindTarget(); + mGlow[1].clear(); } gGlowExtractProgram.bind(); @@ -6557,7 +6567,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b gGL.getTexUnit(0)->unbind(mScreen.getUsage()); - mGlow[2].flush(); + mGlow[1].flush(); } tc1.setVec(0,0); @@ -6589,14 +6599,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b mGlow[i%2].clear(); } - if (i == 0) - { - gGL.getTexUnit(0)->bind(&mGlow[2]); - } - else - { - gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); - } + gGL.getTexUnit(0)->bind(&mGlow[(i+1)%2]); if (i%2 == 0) { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index c88e76f69..5fca4ea91 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -585,7 +585,7 @@ public: LLRenderTarget mWaterDis; //texture for making the glow - LLRenderTarget mGlow[3]; + LLRenderTarget mGlow[2]; //noise map U32 mNoiseMap; diff --git a/indra/newview/rlvui.cpp b/indra/newview/rlvui.cpp index 2f1d59091..405dc7909 100644 --- a/indra/newview/rlvui.cpp +++ b/indra/newview/rlvui.cpp @@ -265,7 +265,7 @@ void RlvUIEnabler::onToggleShowNames(bool fQuitting) else { LLAvatarNameCache::setForceDisplayNames(false); - LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getS32("PhoenixNameSystem") != 0); + LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getS32("PhoenixNameSystem") == 1 || gSavedSettings.getS32("PhoenixNameSystem") == 2); } LLVOAvatar::invalidateNameTags(); // See handleDisplayNamesOptionChanged() } diff --git a/indra/newview/skins/default/colors_base.xml b/indra/newview/skins/default/colors_base.xml index eaed66c4d..651f4c232 100644 --- a/indra/newview/skins/default/colors_base.xml +++ b/indra/newview/skins/default/colors_base.xml @@ -153,6 +153,7 @@ + diff --git a/indra/newview/skins/default/textures/icon_name.tga b/indra/newview/skins/default/textures/icon_name.tga new file mode 100644 index 000000000..54b1a3d6a Binary files /dev/null and b/indra/newview/skins/default/textures/icon_name.tga differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 3552b3eaf..a49fdd786 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -100,7 +100,8 @@ - + + diff --git a/indra/newview/skins/default/xui/en-us/floater_mute.xml b/indra/newview/skins/default/xui/en-us/floater_mute.xml index b1ab1155f..1dd889b62 100644 --- a/indra/newview/skins/default/xui/en-us/floater_mute.xml +++ b/indra/newview/skins/default/xui/en-us/floater_mute.xml @@ -1,14 +1,17 @@ - + + + +