Skip to content
Snippets Groups Projects
llagent.cpp 147 KiB
Newer Older
James Cook's avatar
James Cook committed
/** 
 * @file llagent.cpp
 * @brief LLAgent class implementation
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, 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$
James Cook's avatar
James Cook committed
 */

James Cook's avatar
James Cook committed
#include "llviewerprecompiledheaders.h"
James Cook's avatar
James Cook committed
#include "llagent.h" 
Loren Shih's avatar
Loren Shih committed

#include "pipeline.h"
James Cook's avatar
James Cook committed

Loren Shih's avatar
Loren Shih committed
#include "llagentwearables.h"
#include "llagentui.h"
#include "llappearancemgr.h"
#include "llanimationstates.h"
James Cook's avatar
James Cook committed
#include "llcallingcard.h"
#include "llchannelmanager.h"
James Cook's avatar
James Cook committed
#include "llconsole.h"
#include "lldonotdisturbnotificationstorage.h"
#include "llfirstuse.h"
#include "llfloatercamera.h"
#include "llfloaterperms.h"
#include "llfloaterpreference.h"
Loren Shih's avatar
Loren Shih committed
#include "llfloaterreg.h"
#include "llfloatersnapshot.h"
James Cook's avatar
James Cook committed
#include "llfloatertools.h"
// [SL:KB] - Patch: Chat-GroupOptions | Checked: 2012-06-21 (Catznip-3.3)
#include "llgroupoptions.h"
// [/SL:KB]
James Cook's avatar
James Cook committed
#include "llgroupmgr.h"
#include "llhudmanager.h"
#include "lljoystickbutton.h"
#include "llmorphview.h"
#include "llmoveview.h"
Loren Shih's avatar
Loren Shih committed
#include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
#include "llscriptruntimeperms.h"
James Cook's avatar
James Cook committed
#include "llsky.h"
#include "llsmoothstep.h"
#include "llstartup.h"
James Cook's avatar
James Cook committed
#include "llstatusbar.h"
James Cook's avatar
James Cook committed
#include "lltool.h"
James Cook's avatar
James Cook committed
#include "lltoolmgr.h"
Loren Shih's avatar
Loren Shih committed
#include "lltrans.h"
Loren Shih's avatar
Loren Shih committed
#include "llviewercontrol.h"
#include "llviewerdisplay.h"
Loren Shih's avatar
Loren Shih committed
#include "llviewerjoystick.h"
#include "llviewermediafocus.h"
#include "llviewermenu.h"
James Cook's avatar
James Cook committed
#include "llviewerobjectlist.h"
#include "llviewerparcelmgr.h"
James Cook's avatar
James Cook committed
#include "llviewerstats.h"
#include "llvoavatarself.h"
#include "llwindow.h"
James Cook's avatar
James Cook committed
#include "llworld.h"
#include "llworldmap.h"
// [RLVa:KB] - Checked: 2011-11-04 (RLVa-1.4.4a)
#include "rlvhandler.h"
// [/RLVa:KB]
using namespace LLAvatarAppearanceDefines;
James Cook's avatar
James Cook committed
extern LLMenuBarGL* gMenuBarView;

const BOOL ANIMATE = TRUE;
const U8 AGENT_STATE_TYPING =	0x04;
const U8 AGENT_STATE_EDITING =  0x10;

James Cook's avatar
James Cook committed
// Autopilot constants
const F32 AUTOPILOT_HEIGHT_ADJUST_DISTANCE = 8.f;			// meters
const F32 AUTOPILOT_MIN_TARGET_HEIGHT_OFF_GROUND = 1.f;	// meters
const F32 AUTOPILOT_MAX_TIME_NO_PROGRESS = 1.5f;		// seconds

const F32 MAX_VELOCITY_AUTO_LAND_SQUARED = 4.f * 4.f;
const F64 CHAT_AGE_FAST_RATE = 3.0;
James Cook's avatar
James Cook committed

// fidget constants
const F32 MIN_FIDGET_TIME = 8.f; // seconds
const F32 MAX_FIDGET_TIME = 20.f; // seconds

	LLTeleportRequest();
	virtual ~LLTeleportRequest();

	EStatus getStatus() const          {return mStatus;};
	void    setStatus(EStatus pStatus) {mStatus = pStatus;};

	static std::map<S32, std::string> sTeleportStatusName;
	static const std::string& statusName(EStatus status);
	virtual void toOstream(std::ostream& os) const;

	virtual bool canRestartTeleport();

	virtual void startTeleport() = 0;
	virtual void restartTeleport();
std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending, "kPending" },
																	  { kStarted, "kStarted" },
																	  { kFailed, "kFailed" },
																	  { kRestartPending, "kRestartPending"} };

class LLTeleportRequestViaLandmark : public LLTeleportRequest
{
public:
	LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
	virtual ~LLTeleportRequestViaLandmark();

	virtual void toOstream(std::ostream& os) const;

	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 void toOstream(std::ostream& os) const;

	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 void toOstream(std::ostream& os) const;

	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:
// [RLVa:KB] - Checked: RLVa-2.0.0
	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal, const LLVector3& look_at);
// [/RLVa:KB]
//	LLTeleportRequestViaLocationLookAt(const LLVector3d &pPosGlobal);
	virtual ~LLTeleportRequestViaLocationLookAt();

	virtual void toOstream(std::ostream& os) const;

	virtual bool canRestartTeleport();

	virtual void startTeleport();
	virtual void restartTeleport();
// [RLVa:KB] - Checked: RLVa-2.0.0
	const LLVector3& getLookAt() const { return mLookAt; }
// [/RLVa:KB]
// [RLVa:KB] - Checked: RLVa-2.0.0
	LLVector3 mLookAt;
// [/RLVa:KB]
//--------------------------------------------------------------------
James Cook's avatar
James Cook committed
// Statics
//

/// minimum time after setting away state before coming back based on movement
const F32 LLAgent::MIN_AFK_TIME = 10.0f;

James Cook's avatar
James Cook committed
const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f;

std::map<std::string, std::string> LLAgent::sTeleportErrorMessages;
std::map<std::string, std::string> LLAgent::sTeleportProgressMessages;
James Cook's avatar
James Cook committed
class LLAgentFriendObserver : public LLFriendObserver
{
public:
	LLAgentFriendObserver() {}
	virtual ~LLAgentFriendObserver() {}
	virtual void changed(U32 mask);
};

void LLAgentFriendObserver::changed(U32 mask)
{
	// if there's a change we're interested in.
	if((mask & (LLFriendObserver::POWERS)) != 0)
	{
		gAgent.friendsChanged();
	}
}

bool handleSlowMotionAnimation(const LLSD& newvalue)
{
	if (newvalue.asBoolean())
	{
		gAgentAvatarp->setAnimTimeFactor(0.2f);
		gAgentAvatarp->setAnimTimeFactor(1.0f);
void LLAgent::setCanEditParcel() // called via mParcelChangedSignal
{
	bool can_edit = LLToolMgr::getInstance()->canEdit();
	gAgent.mCanEditParcel = can_edit;
}

// static
bool LLAgent::isActionAllowed(const LLSD& sdname)
{
	bool retval = false;

	const std::string& param = sdname.asString();

        bool allow_agent_voice = false;
        LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
        if (channel != NULL)
        {
            if (channel->getSessionName().empty() && channel->getSessionID().isNull())
            {
                // default channel
                allow_agent_voice = LLViewerParcelMgr::getInstance()->allowAgentVoice();
            }
            else
            {
                allow_agent_voice = channel->isActive() && channel->callStarted();
            }
        }

        if (gAgent.isVoiceConnected() &&
            allow_agent_voice &&
            !LLVoiceClient::getInstance()->inTuningMode())
void LLAgent::pressMicrophone(const LLSD& name)
	LLFirstUse::speak(false);
	 LLVoiceClient::getInstance()->inputUserControlState(true);
}
// static 
void LLAgent::releaseMicrophone(const LLSD& name)
{
	LLVoiceClient::getInstance()->inputUserControlState(false);
// static
void LLAgent::toggleMicrophone(const LLSD& name)
{
	LLVoiceClient::getInstance()->toggleUserPTTState();
}

// static
bool LLAgent::isMicrophoneOn(const LLSD& sdname)
{
	return LLVoiceClient::getInstance()->getUserPTTState();
James Cook's avatar
James Cook committed
// ************************************************************
// Enabled this definition to compile a 'hacked' viewer that
// locally believes the end user has godlike powers.
// #define HACKED_GODLIKE_VIEWER
// For a toggled version, see viewer.h for the
// TOGGLE_HACKED_GODLIKE_VIEWER define, instead.
// ************************************************************

// Constructors and Destructors

// JC - Please try to make this order match the order in the header
// file.  Otherwise it's hard to find variables that aren't initialized.
//-----------------------------------------------------------------------------
// LLAgent()
//-----------------------------------------------------------------------------
LLAgent::LLAgent() :
James Cook's avatar
James Cook committed
	mGroupPowers(0),
	mHideGroupTitle(FALSE),
James Cook's avatar
James Cook committed
	mGroupID(),
James Cook's avatar
James Cook committed
	mInitialized(FALSE),

	mDoubleTapRunTimer(),
	mDoubleTapRunMode(DOUBLETAP_NONE),

	mbAlwaysRun(false),
//	mbRunning(false),
// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
	mbTempRun(false),
// [/RLVa:KB]
	mbTeleportKeepsLookAt(false),
	mAgentAccess(new LLAgentAccess(gSavedSettings)),
	mTeleportFinishedSlot(),
	mTeleportFailedSlot(),
	mIsMaturityRatingChangingDuringTeleport(false),
	mIsDoSendMaturityPreferenceToServer(false),
	mMaturityPreferenceRequestId(0U),
	mMaturityPreferenceResponseId(0U),
	mMaturityPreferenceNumRetries(0U),
	mLastKnownRequestMaturity(SIM_ACCESS_MIN),
	mLastKnownResponseMaturity(SIM_ACCESS_MIN),
	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
	mTeleportState(TELEPORT_NONE),
James Cook's avatar
James Cook committed
	mRegionp(NULL),

	mAgentOriginGlobal(),
	mPositionGlobal(),
    mLastTestGlobal(),
James Cook's avatar
James Cook committed

	mDistanceTraveled(0.F),
James Cook's avatar
James Cook committed
	mLastPositionGlobal(LLVector3d::zero),

	mRenderState(0),
	mTypingTimer(),

	mViewsPushed(FALSE),

	mCustomAnim(FALSE),
James Cook's avatar
James Cook committed
	mShowAvatar(TRUE),
	mFrameAgent(),

James Cook's avatar
James Cook committed

	mControlFlags(0x00000000),
	mbFlagsDirty(FALSE),
	mbFlagsNeedReset(FALSE),

	mAutoPilot(FALSE),
	mAutoPilotFlyOnStop(FALSE),
James Cook's avatar
James Cook committed
	mAutoPilotTargetGlobal(),
	mAutoPilotStopDistance(1.f),
	mAutoPilotUseRotation(FALSE),
	mAutoPilotTargetFacing(LLVector3::zero),
	mAutoPilotTargetDist(0.f),
	mAutoPilotNoProgressFrameCount(0),
	mAutoPilotRotationThreshold(0.f),
James Cook's avatar
James Cook committed
	mAutoPilotFinishedCallback(NULL),
	mAutoPilotCallbackData(NULL),
	
	mMovementResetCamera(true),

	mEffectColor(new LLUIColor(LLColor4(0.f, 1.f, 1.f, 1.f))),
James Cook's avatar
James Cook committed
	mHaveHomePosition(FALSE),
	mHomeRegionHandle( 0 ),
	mNearChatRadius(CHAT_NORMAL_RADIUS / 2.f),
James Cook's avatar
James Cook committed

	mNextFidgetTime(0.f),
	mCurrentFidget(0),
	mFirstLogin(FALSE),
	mOutfitChosen(FALSE),

	mMouselookModeInSignal(NULL),
	mMouselookModeOutSignal(NULL)
James Cook's avatar
James Cook committed
{
	for (U32 i = 0; i < TOTAL_CONTROLS; i++)
James Cook's avatar
James Cook committed
	{
		mControlsTakenCount[i] = 0;
		mControlsTakenPassedOnCount[i] = 0;
	}

	addParcelChangedCallback(&setCanEditParcel);

	mMoveTimer.stop();
James Cook's avatar
James Cook committed
}

// Requires gSavedSettings to be initialized.
//-----------------------------------------------------------------------------
// init()
//-----------------------------------------------------------------------------
void LLAgent::init()
{
	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO);
	gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
	
	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
James Cook's avatar
James Cook committed

	setFlying( gSavedSettings.getBOOL("FlyingAtExit") );

	*mEffectColor = LLUIColorTable::instance().getColor("EffectColor");
James Cook's avatar
James Cook committed

	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<U8>(gSavedSettings.getU32("PreferredMaturity"));
	mLastKnownRequestMaturity = mLastKnownResponseMaturity;
	mIsDoSendMaturityPreferenceToServer = true;
	auto controlp = gSavedSettings.getControl("AlchemyMotionResetsCamera");
	controlp->getSignal()->connect([&](LLControlVariable* control, const LLSD& new_val, const LLSD&) { mMovementResetCamera = new_val.asBoolean(); });
	mMovementResetCamera = controlp->getValue().asBoolean();

	if (!mTeleportFinishedSlot.connected())
	{
		mTeleportFinishedSlot = LLViewerParcelMgr::getInstance()->setTeleportFinishedCallback(boost::bind(&LLAgent::handleTeleportFinished, this));
	}
	if (!mTeleportFailedSlot.connected())
	{
		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
	}
	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());

	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AGENT);
James Cook's avatar
James Cook committed
	mInitialized = TRUE;
}

//-----------------------------------------------------------------------------
// cleanup()
//-----------------------------------------------------------------------------
void LLAgent::cleanup()
{
	mRegionp = NULL;
    mTeleportRequest = NULL;
    mTeleportCanceled = NULL;
	if (mTeleportFinishedSlot.connected())
	{
		mTeleportFinishedSlot.disconnect();
	}
	if (mTeleportFailedSlot.connected())
	{
		mTeleportFailedSlot.disconnect();
	}
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// LLAgent()
//-----------------------------------------------------------------------------
LLAgent::~LLAgent()
{
	cleanup();

	delete mAgentAccess;
	mAgentAccess = NULL;
	delete mEffectColor;
	mEffectColor = NULL;
	delete mTeleportSourceSLURL;
	mTeleportSourceSLURL = NULL;
// Handle any actions that need to be performed when the main app gains focus
// (such as through alt-tab).
//-----------------------------------------------------------------------------
// onAppFocusGained()
//-----------------------------------------------------------------------------
void LLAgent::onAppFocusGained()
{
//	if (CAMERA_MODE_MOUSELOOK == gAgentCamera.getCameraMode())
//	{
//		gAgentCamera.changeCameraToDefault();
//		LLToolMgr::getInstance()->clearSavedTool();
//	}
James Cook's avatar
James Cook committed
void LLAgent::ageChat()
{
	if (isAgentAvatarValid())
James Cook's avatar
James Cook committed
	{
		// get amount of time since I last chatted
		F64 elapsed_time = (F64)gAgentAvatarp->mChatTimer.getElapsedTimeF32();
James Cook's avatar
James Cook committed
		// add in frame time * 3 (so it ages 4x)
		gAgentAvatarp->mChatTimer.setAge(elapsed_time + (F64)gFrameDTClamped * (CHAT_AGE_FAST_RATE - 1.0));
James Cook's avatar
James Cook committed
	}
}

//-----------------------------------------------------------------------------
// moveAt()
//-----------------------------------------------------------------------------
Steven Bennetts's avatar
Steven Bennetts committed
void LLAgent::moveAt(S32 direction, bool reset)
James Cook's avatar
James Cook committed
{
	mMoveTimer.reset();
	LLFirstUse::notMoving(false);

James Cook's avatar
James Cook committed
	// age chat timer so it fades more quickly when you are intentionally moving
	ageChat();

	gAgentCamera.setAtKey(LLAgentCamera::directionToKey(direction));
James Cook's avatar
James Cook committed

	if (direction > 0)
	{
		setControlFlags(AGENT_CONTROL_AT_POS | AGENT_CONTROL_FAST_AT);
	}
	else if (direction < 0)
	{
		setControlFlags(AGENT_CONTROL_AT_NEG | AGENT_CONTROL_FAST_AT);
	}

Steven Bennetts's avatar
Steven Bennetts committed
	if (reset)
	{
		gAgentCamera.resetView(mMovementResetCamera);
Steven Bennetts's avatar
Steven Bennetts committed
	}
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// moveAtNudge()
//-----------------------------------------------------------------------------
void LLAgent::moveAtNudge(S32 direction)
{
	mMoveTimer.reset();
	LLFirstUse::notMoving(false);

James Cook's avatar
James Cook committed
	// age chat timer so it fades more quickly when you are intentionally moving
	ageChat();

	gAgentCamera.setWalkKey(LLAgentCamera::directionToKey(direction));
James Cook's avatar
James Cook committed

	if (direction > 0)
	{
		setControlFlags(AGENT_CONTROL_NUDGE_AT_POS);
	}
	else if (direction < 0)
	{
		setControlFlags(AGENT_CONTROL_NUDGE_AT_NEG);
	}

	gAgentCamera.resetView(mMovementResetCamera);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// moveLeft()
//-----------------------------------------------------------------------------
void LLAgent::moveLeft(S32 direction)
{
	mMoveTimer.reset();
	LLFirstUse::notMoving(false);

James Cook's avatar
James Cook committed
	// age chat timer so it fades more quickly when you are intentionally moving
	ageChat();

	gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction));
James Cook's avatar
James Cook committed

	if (direction > 0)
	{
		setControlFlags(AGENT_CONTROL_LEFT_POS | AGENT_CONTROL_FAST_LEFT);
	}
	else if (direction < 0)
	{
		setControlFlags(AGENT_CONTROL_LEFT_NEG | AGENT_CONTROL_FAST_LEFT);
	}

	gAgentCamera.resetView(mMovementResetCamera);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// moveLeftNudge()
//-----------------------------------------------------------------------------
void LLAgent::moveLeftNudge(S32 direction)
{
	mMoveTimer.reset();
	LLFirstUse::notMoving(false);

James Cook's avatar
James Cook committed
	// age chat timer so it fades more quickly when you are intentionally moving
	ageChat();

	gAgentCamera.setLeftKey(LLAgentCamera::directionToKey(direction));
James Cook's avatar
James Cook committed

	if (direction > 0)
	{
		setControlFlags(AGENT_CONTROL_NUDGE_LEFT_POS);
	}
	else if (direction < 0)
	{
		setControlFlags(AGENT_CONTROL_NUDGE_LEFT_NEG);
	}

	gAgentCamera.resetView(mMovementResetCamera);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// moveUp()
//-----------------------------------------------------------------------------
void LLAgent::moveUp(S32 direction)
{
Kitty Barnett's avatar
Kitty Barnett committed
// [RLVa:KB] - Checked: RLVa-2.2 (@jump)
	if ( (!RlvActions::canJump()) && (direction > 0) && (!getFlying()) )
	{
		return;
	}
// [/Sl:KB]

	mMoveTimer.reset();
	LLFirstUse::notMoving(false);

James Cook's avatar
James Cook committed
	// age chat timer so it fades more quickly when you are intentionally moving
	ageChat();

	gAgentCamera.setUpKey(LLAgentCamera::directionToKey(direction));
James Cook's avatar
James Cook committed

	if (direction > 0)
	{
		setControlFlags(AGENT_CONTROL_UP_POS | AGENT_CONTROL_FAST_UP);
	}
	else if (direction < 0)
	{
		setControlFlags(AGENT_CONTROL_UP_NEG | AGENT_CONTROL_FAST_UP);
	}

	gAgentCamera.resetView(mMovementResetCamera);
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// moveYaw()
//-----------------------------------------------------------------------------
Steven Bennetts's avatar
Steven Bennetts committed
void LLAgent::moveYaw(F32 mag, bool reset_view)
James Cook's avatar
James Cook committed
{
James Cook's avatar
James Cook committed

	if (mag > 0)
	{
		setControlFlags(AGENT_CONTROL_YAW_POS);
	}
	else if (mag < 0)
	{
		setControlFlags(AGENT_CONTROL_YAW_NEG);
	}

Steven Bennetts's avatar
Steven Bennetts committed
    if (reset_view)
	{
        gAgentCamera.resetView(mMovementResetCamera);
Steven Bennetts's avatar
Steven Bennetts committed
	}
James Cook's avatar
James Cook committed
}

//-----------------------------------------------------------------------------
// movePitch()
//-----------------------------------------------------------------------------
void LLAgent::movePitch(F32 mag)
James Cook's avatar
James Cook committed
{
James Cook's avatar
James Cook committed

James Cook's avatar
James Cook committed
	{
		setControlFlags(AGENT_CONTROL_PITCH_POS);
James Cook's avatar
James Cook committed
	}
James Cook's avatar
James Cook committed
	{
		setControlFlags(AGENT_CONTROL_PITCH_NEG);
	}
}


// Does this parcel allow you to fly?
BOOL LLAgent::canFly()
{
// [RLVa:KB] - Checked: RLVa-1.0
	if (!RlvActions::canFly())
	{
		return FALSE;
	}
// [/RLVa:KB]
James Cook's avatar
James Cook committed
	if (isGodlike()) return TRUE;

	LLViewerRegion* regionp = getRegion();
	if (regionp && regionp->getBlockFly()) return FALSE;
	
	LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
James Cook's avatar
James Cook committed
	if (!parcel) return FALSE;

	// Allow owners to fly on their own land.
	if (LLViewerParcelMgr::isParcelOwnedByAgent(parcel, GP_LAND_ALLOW_FLY))
	{
		return TRUE;
	}

	return parcel->getAllowFly();
}

BOOL LLAgent::getFlying() const
{ 
	return mControlFlags & AGENT_CONTROL_FLY; 
}
James Cook's avatar
James Cook committed

//-----------------------------------------------------------------------------
// setFlying()
//-----------------------------------------------------------------------------
void LLAgent::setFlying(BOOL fly, BOOL fail_sound)
James Cook's avatar
James Cook committed
{
	if (isAgentAvatarValid())
James Cook's avatar
James Cook committed
	{
		// *HACK: Don't allow to start the flying mode if we got ANIM_AGENT_STANDUP signal
		// because in this case we won't get a signal to start avatar flying animation and
		// it will be walking with flying mode "ON" indication. However we allow to switch
		// the flying mode off if we get ANIM_AGENT_STANDUP signal. See process_avatar_animation().
		if(fly && gAgentAvatarp->mSignaledAnimations.find(ANIM_AGENT_STANDUP) != gAgentAvatarp->mSignaledAnimations.end())
James Cook's avatar
James Cook committed
		{
			return;
		}

		// don't allow taking off while sitting
		if (fly && gAgentAvatarp->isSitting())
James Cook's avatar
James Cook committed
		{
			return;
		}
	}

	if (fly)
	{
// [RLVa:KB] - Checked: RLVa-1.0
		if (!RlvActions::canFly())
		{
			return;
		}
// [/RLVa:KB]

James Cook's avatar
James Cook committed
		BOOL was_flying = getFlying();
		if (!canFly() && !was_flying)
James Cook's avatar
James Cook committed
		{
			// parcel doesn't let you start fly
			// gods can always fly
			// and it's OK if you're already flying
			make_ui_sound("UISndBadKeystroke");
James Cook's avatar
James Cook committed
		}
		if( !was_flying )
		{
James Cook's avatar
James Cook committed
		}
		setControlFlags(AGENT_CONTROL_FLY);
	}
	else
	{
		clearControlFlags(AGENT_CONTROL_FLY);
	}
Steven Bennetts's avatar
Steven Bennetts committed


	// Update Movement Controls according to Fly mode
	LLFloaterMove::setFlyingMode(fly);

James Cook's avatar
James Cook committed
	mbFlagsDirty = TRUE;
}


// UI based mechanism of setting fly state
//-----------------------------------------------------------------------------
// toggleFlying()
//-----------------------------------------------------------------------------
James Cook's avatar
James Cook committed
void LLAgent::toggleFlying()
{
	if ( gAgent.mAutoPilot )
	{
		LLToolPie::instance().stopClickToWalk();
	}
	BOOL fly = !gAgent.getFlying();
James Cook's avatar
James Cook committed

	gAgent.mMoveTimer.reset();
	LLFirstUse::notMoving(false);

	gAgentCamera.resetView(gAgent.mMovementResetCamera);
}

// static
bool LLAgent::enableFlying()
{
	BOOL sitting = FALSE;
	if (isAgentAvatarValid())
		sitting = gAgentAvatarp->isSitting();
// static
bool LLAgent::isSitting()
{
    BOOL sitting = FALSE;
    if (isAgentAvatarValid())
    {
        sitting = gAgentAvatarp->isSitting();
    }
    return sitting;
}

Steven Bennetts's avatar
Steven Bennetts committed
void LLAgent::standUp()
{
//	setControlFlags(AGENT_CONTROL_STAND_UP);
// [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Added: RLVa-1.2.0a
	// RELEASE-RLVa: [SL-2.0.0] Check this function's callers since usually they require explicit blocking
	if ( (!rlv_handler_t::isEnabled()) || (RlvActions::canStand()) )
	{
		setControlFlags(AGENT_CONTROL_STAND_UP);
	}
// [/RLVa:KB]
Steven Bennetts's avatar
Steven Bennetts committed
}

void LLAgent::changeParcels()
{
	LL_DEBUGS("AgentLocation") << "Calling ParcelChanged callbacks" << LL_ENDL;
	// Notify anything that wants to know about parcel changes
	mParcelChangedSignal();
}

boost::signals2::connection LLAgent::addParcelChangedCallback(parcel_changed_callback_t cb)
{
	return mParcelChangedSignal.connect(cb);
}

// static
void LLAgent::capabilityReceivedCallback(const LLUUID &region_id)
{
    LLViewerRegion* region = gAgent.getRegion();
    if (region && region->getRegionID() == region_id)
    {
        region->requestSimulatorFeatures();
        LLAppViewer::instance()->updateNameLookupUrl();
    }
}


James Cook's avatar
James Cook committed
//-----------------------------------------------------------------------------
// setRegion()
//-----------------------------------------------------------------------------
void LLAgent::setRegion(LLViewerRegion *regionp)
{
	llassert(regionp);
	if (mRegionp != regionp)
	{

		LL_INFOS("AgentLocation","Teleport") << "Moving agent into region: handle " << regionp->getHandle() 
											 << " id " << regionp->getRegionID()
											 << " name " << regionp->getName()
											 << " previous region "
											 << (mRegionp ? mRegionp->getRegionID() : LLUUID::null)
											 << LL_ENDL;
James Cook's avatar
James Cook committed
		if (mRegionp)
		{
			// We've changed regions, we're now going to change our agent coordinate frame.
			mAgentOriginGlobal = regionp->getOriginGlobal();
			LLVector3d agent_offset_global = mRegionp->getOriginGlobal();

			LLVector3 delta;
			delta.setVec(regionp->getOriginGlobal() - mRegionp->getOriginGlobal());

			setPositionAgent(getPositionAgent() - delta);

			LLVector3 camera_position_agent = LLViewerCamera::getInstance()->getOrigin();
			LLViewerCamera::getInstance()->setOrigin(camera_position_agent - delta);
James Cook's avatar
James Cook committed

			// Update all of the regions.
			LLWorld::getInstance()->updateAgentOffset(agent_offset_global);
James Cook's avatar
James Cook committed

			// Hack to keep sky in the agent's region, otherwise it may get deleted - DJS 08/02/02
			// *TODO: possibly refactor into gSky->setAgentRegion(regionp)? -Brad
James Cook's avatar
James Cook committed
			if (gSky.mVOSkyp)
			{
				gSky.mVOSkyp->setRegion(regionp);
			}
			if (gSky.mVOGroundp)
			{
				gSky.mVOGroundp->setRegion(regionp);
			}

            if (regionp->capabilitiesReceived())
            {
                regionp->requestSimulatorFeatures();
                LLAppViewer::instance()->updateNameLookupUrl();
                regionp->setCapabilitiesReceivedCallback(LLAgent::capabilityReceivedCallback);
James Cook's avatar
James Cook committed
		}
		else
		{