summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt12
-rw-r--r--indra/newview/FixBundle.cmake.in6
-rw-r--r--indra/newview/FixPackage.cmake.in6
-rw-r--r--indra/newview/app_settings/settings.xml89
-rw-r--r--indra/newview/llagent.cpp18
-rw-r--r--indra/newview/llagentcamera.cpp86
-rw-r--r--indra/newview/llagentcamera.h9
-rw-r--r--indra/newview/llappviewer.cpp10
-rw-r--r--indra/newview/llappviewerlinux.cpp4
-rw-r--r--indra/newview/llavataractions.cpp85
-rw-r--r--indra/newview/llavataractions.h6
-rw-r--r--indra/newview/llpanelpeoplemenus.cpp16
-rw-r--r--indra/newview/llpanelpeoplemenus.h1
-rw-r--r--indra/newview/llquickprefs.cpp23
-rw-r--r--indra/newview/llquickprefs.h5
-rw-r--r--indra/newview/llviewerdisplay.cpp6
-rw-r--r--indra/newview/llviewermedia.cpp6
-rw-r--r--indra/newview/llviewermenu.cpp65
-rw-r--r--indra/newview/llviewermessage.cpp11
-rw-r--r--indra/newview/skins/default/xui/en/floater_quick_prefs.xml126
-rw-r--r--indra/newview/skins/default/xui/en/menu_avatar_other.xml16
-rw-r--r--indra/newview/skins/default/xui/en/menu_people_nearby.xml16
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml12
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_move.xml755
24 files changed, 1034 insertions, 355 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index f19716af7e..e070fb3da3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -50,9 +50,6 @@ include(VisualLeakDetector)
#include(VulkanGltf)
include(ZLIBNG)
include(LLPrimitive)
-if (CMAKE_SYSTEM_PROCESSOR MATCHES aarch64)
- include(UnixInstall)
-endif ()
if (ENABLE_MEDIA_PLUGINS)
include(LibVLCPlugin)
@@ -1534,7 +1531,6 @@ if (NOT (DARWIN OR WINDOWS))
llappviewerlinux.cpp
PROPERTIES
COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
- COMPILE_FLAGS "-DAPP_PLUGIN_DIR=\\\"${INSTALL_LIBRARY_DIR}\\\""
)
#LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
if (NOT CMAKE_CXX_COMPILER_ID MATCHES AppleClang)
@@ -2206,8 +2202,14 @@ endif ()
if (ENABLE_MEDIA_PLUGINS)
target_link_libraries(${VIEWER_BINARY_NAME} ll::libvlc )
+ # Tell the viewer source which media-library version headers are
+ # actually available in this build, so version reporting in
+ # llappviewer.cpp is gated on the build configuration rather than on
+ # a CPU/compiler macro. Mirrors the link availability above exactly.
+ target_compile_definitions(${VIEWER_BINARY_NAME} PRIVATE LL_VLC=1)
if (DARWIN OR LINUX)
target_link_libraries(${VIEWER_BINARY_NAME} ll::cef )
+ target_compile_definitions(${VIEWER_BINARY_NAME} PRIVATE LL_CEF=1)
endif ()
endif ()
@@ -2399,7 +2401,7 @@ if (LINUX)
set(CPACK_RPM_PACKAGE_DESCRIPTION ${VIEWER_PACKAGE_DESCRIPTION}
CACHE STRING "RPM package description.")
if (${LINUX_DISTRO} MATCHES fedora)
- set(CPACK_RPM_PACKAGE_REQUIRES "freealut, apr-util, boost-fiber, boost-program-options, boost-regex, boost-thread, boost-url, cef, expat, fltk, mesa-libGLU, hunspell, libnghttp2, openjpeg, sdl2-compat, vlc-libs, vlc-plugins-base, libvorbis"
+ set(CPACK_RPM_PACKAGE_REQUIRES "freealut, apr-util, boost-fiber, boost-program-options, boost-regex, boost-thread, boost-url, cef, expat, fltk, mesa-libGLU, hunspell, minizip-ng-compat, libnghttp2, openjpeg, sdl2-compat, vlc-libs, vlc-plugins-base, libvorbis"
CACHE STRING "RPM package requirements.")
else ()
set(CPACK_RPM_PACKAGE_REQUIRES "libalut0, libapr-util1-0, libboost_fiber1_91_0, libboost_program_options1_91_0, libboost_regex1_91_0, libboost_thread1_91_0, libboost_url1_91_0, libboost_url1_91_0-x86-64-v3, libpng16-16 expat, libfltk1_3, libGLU1, libhunspell-1_7-0, libnghttp2-14, openjpeg2, libSDL2-2_0-0, libvlc5, libvorbis0"
diff --git a/indra/newview/FixBundle.cmake.in b/indra/newview/FixBundle.cmake.in
index 77b4683c88..a2dfadd7ef 100644
--- a/indra/newview/FixBundle.cmake.in
+++ b/indra/newview/FixBundle.cmake.in
@@ -158,9 +158,9 @@ execute_process(
COMMAND lipo libbz2.1.0.8.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
-output libbz2.1.0.8.dylib
- COMMAND lipo libexpat.1.11.3.dylib
+ COMMAND lipo libexpat.1.12.1.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
- -output libexpat.1.11.3.dylib
+ -output libexpat.1.12.1.dylib
COMMAND lipo libfreetype.6.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
-output libfreetype.6.dylib
@@ -258,7 +258,7 @@ execute_process(
Frameworks/libbrotlidec.1.2.0.dylib
Frameworks/libbz2.1.0.8.dylib
Frameworks/libdiscord_partner_sdk.dylib
- Frameworks/libexpat.1.11.3.dylib
+ Frameworks/libexpat.1.12.1.dylib
Frameworks/libfreetype.6.dylib
Frameworks/libhunspell-1.7.0.dylib
Frameworks/libiconv.2.dylib
diff --git a/indra/newview/FixPackage.cmake.in b/indra/newview/FixPackage.cmake.in
index e67026aabb..4ae777c2f4 100644
--- a/indra/newview/FixPackage.cmake.in
+++ b/indra/newview/FixPackage.cmake.in
@@ -158,9 +158,9 @@ execute_process(
COMMAND lipo libbz2.1.0.8.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
-output libbz2.1.0.8.dylib
- COMMAND lipo libexpat.1.11.3.dylib
+ COMMAND lipo libexpat.1.12.1.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
- -output libexpat.1.11.3.dylib
+ -output libexpat.1.12.1.dylib
COMMAND lipo libfreetype.6.dylib
-thin ${CMAKE_OSX_ARCHITECTURES}
-output libfreetype.6.dylib
@@ -258,7 +258,7 @@ execute_process(
Frameworks/libbrotlidec.1.2.0.dylib
Frameworks/libbz2.1.0.8.dylib
Frameworks/libdiscord_partner_sdk.dylib
- Frameworks/libexpat.1.11.3.dylib
+ Frameworks/libexpat.1.12.1.dylib
Frameworks/libfreetype.6.dylib
Frameworks/libhunspell-1.7.0.dylib
Frameworks/libiconv.2.dylib
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 481cafafd1..8b6c5e2e1a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1365,6 +1365,63 @@
<integer>1</integer>
</map>
<!-- End NaCl/Firestorm port -->
+ <!-- OTS over-the-shoulder aim settings -->
+ <key>OTSEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>When true, M key enters OTS shoulder cam instead of first-person mouselook</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>OTSCameraDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>OTS camera distance behind avatar (meters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>3.0</real>
+ </map>
+ <key>OTSCameraSide</key>
+ <map>
+ <key>Comment</key>
+ <string>OTS camera side offset (negative = right of avatar)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>-0.5</real>
+ </map>
+ <key>OTSCameraHeight</key>
+ <map>
+ <key>Comment</key>
+ <string>OTS camera height above avatar root (meters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
+ <key>OTSFocusDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>OTS focus point distance in front of avatar (meters)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>10.0</real>
+ </map>
+ <!-- End OTS settings -->
<key>CameraOffset</key>
<map>
<key>Comment</key>
@@ -1402,8 +1459,8 @@
<key>Value</key>
<array>
<real>-3.0</real>
- <real>0.5</real>
- <real>0.2</real>
+ <real>0.0</real>
+ <real>0.75</real>
</array>
</map>
<key>CameraOffsetScale</key>
@@ -3272,9 +3329,9 @@
<string>Vector3D</string>
<key>Value</key>
<array>
- <real>0.9</real>
- <real>0.5</real>
- <real>0.2</real>
+ <real>1.0</real>
+ <real>0.0</real>
+ <real>1.0</real>
</array>
</map>
<key>AvatarSitRotation</key>
@@ -4684,6 +4741,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>KeepCameraOnLocalTeleport</key>
+ <map>
+ <key>Comment</key>
+ <string>Do not reset the camera position or mode when teleporting within the same region.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>DisableTeleportScreens</key>
+ <map>
+ <key>Comment</key>
+ <string>Do not show the fullscreen teleport progress/black screen during teleports.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MiniMapAutoCenter</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 23647487b0..75a9ef58fc 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -2123,6 +2123,13 @@ std::ostream& operator<<(std::ostream &s, const LLAgent &agent)
//-----------------------------------------------------------------------------
bool LLAgent::needsRenderAvatar()
{
+ // OTS mode: always render avatar — we are in third-person even though
+ // mouselook input is active.
+ if (gAgentCamera.cameraOTS())
+ {
+ return mShowAvatar && mOutfitChosen;
+ }
+
if (gAgentCamera.cameraMouselook() && !LLVOAvatar::sVisibleInFirstPerson)
{
return false;
@@ -2134,6 +2141,11 @@ bool LLAgent::needsRenderAvatar()
// true if we need to render your own avatar's head.
bool LLAgent::needsRenderHead()
{
+ // OTS mode: always render head — avatar is fully visible.
+ if (gAgentCamera.cameraOTS())
+ {
+ return mShowAvatar;
+ }
return (LLVOAvatar::sVisibleInFirstPerson && LLPipeline::sReflectionRender) || (mShowAvatar && !gAgentCamera.cameraMouselook());
}
@@ -2247,7 +2259,8 @@ void LLAgent::endAnimationUpdateUI()
}
// clean up UI from mode we're leaving
- if (gAgentCamera.getLastCameraMode() == CAMERA_MODE_MOUSELOOK )
+ if (gAgentCamera.getLastCameraMode() == CAMERA_MODE_MOUSELOOK
+ || gAgentCamera.getLastCameraMode() == CAMERA_MODE_OTS)
{
gToolBarView->setToolBarsVisible(true);
// show mouse cursor
@@ -2369,7 +2382,8 @@ void LLAgent::endAnimationUpdateUI()
//---------------------------------------------------------------------
// Set up UI for mode we're entering
//---------------------------------------------------------------------
- if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+ if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK
+ || gAgentCamera.getCameraMode() == CAMERA_MODE_OTS)
{
// clean up UI
// first show anything hidden by UI toggle
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 369a6d3697..6f9f8bfa2a 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1176,7 +1176,7 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
LLVector3 headLookAxis;
LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
- if (cameraMouselook())
+ if (cameraMouselook() || cameraOTS())
{
lookAtType = LOOKAT_TARGET_MOUSELOOK;
}
@@ -1409,7 +1409,7 @@ void LLAgentCamera::updateCamera()
gAgent.setShowAvatar(true);
}
- if (isAgentAvatarValid() && (mCameraMode != CAMERA_MODE_MOUSELOOK))
+ if (isAgentAvatarValid() && mCameraMode != CAMERA_MODE_MOUSELOOK)
{
gAgentAvatarp->updateAttachmentVisibility(mCameraMode);
}
@@ -1497,7 +1497,8 @@ void LLAgentCamera::updateCamera()
}
gAgent.setLastPositionGlobal(global_pos);
- if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook())
+ // Exclude OTS — shoulder camera position must not be overridden by head-tracking.
+ if (LLVOAvatar::sVisibleInFirstPerson && isAgentAvatarValid() && !gAgentAvatarp->isSitting() && cameraMouselook() && !cameraOTS())
{
LLVector3 head_pos = gAgentAvatarp->mHeadp->getWorldPosition() +
LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() +
@@ -1598,6 +1599,19 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
mFocusTargetGlobal = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedFocus());
return mFocusTargetGlobal;
}
+ else if (mCameraMode == CAMERA_MODE_OTS)
+ {
+ // Focus in front of avatar at aim height
+ static LLCachedControl<F32> ots_focus_dist(gSavedSettings, "OTSFocusDistance", 10.0f);
+ static LLCachedControl<F32> ots_height(gSavedSettings, "OTSCameraHeight", 0.5f);
+ static LLCachedControl<F32> ots_side(gSavedSettings, "OTSCameraSide", -0.5f);
+ LLVector3 focus_local((F32)ots_focus_dist, (F32)ots_side * 0.3f, (F32)ots_height * 0.5f);
+ LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+ LLVector3 focus_world = focus_local * agent_rot;
+ LLVector3d avatar_pos = gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
+ mFocusTargetGlobal = avatar_pos + LLVector3d(focus_world);
+ return mFocusTargetGlobal;
+ }
else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
{
LLVector3d at_axis(1.0, 0.0, 0.0);
@@ -1776,6 +1790,18 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(bool *hit_limit)
{
camera_position_global = gAgent.getPosGlobalFromAgent(mFollowCam.getSimulatedPosition());
}
+ else if (mCameraMode == CAMERA_MODE_OTS)
+ {
+ // Shoulder offset camera — avatar-local space: X=forward, Y=left, Z=up
+ static LLCachedControl<F32> ots_dist(gSavedSettings, "OTSCameraDistance", 3.0f);
+ static LLCachedControl<F32> ots_side(gSavedSettings, "OTSCameraSide", -0.5f);
+ static LLCachedControl<F32> ots_height(gSavedSettings, "OTSCameraHeight", 0.5f);
+ LLVector3 local_offset(-(F32)ots_dist, (F32)ots_side, (F32)ots_height);
+ LLQuaternion agent_rot = gAgent.getFrameAgent().getQuaternion();
+ LLVector3 world_offset = local_offset * agent_rot;
+ LLVector3d avatar_pos = gAgent.getPosGlobalFromAgent(getAvatarRootPosition());
+ camera_position_global = avatar_pos + LLVector3d(world_offset);
+ }
else if (mCameraMode == CAMERA_MODE_MOUSELOOK)
{
if (!isAgentAvatarValid() || gAgentAvatarp->mDrawable.isNull())
@@ -2244,6 +2270,58 @@ void LLAgentCamera::changeCameraToDefault()
//-----------------------------------------------------------------------------
+// changeCameraToOTS()
+// Over-the-shoulder aim mode.
+// Calls changeCameraToMouselook() to inherit ALL of its input setup
+// (cursor hiding, mouse capture, control flags, focus management),
+// then immediately overrides mCameraMode to CAMERA_MODE_OTS so that
+// calcCameraPositionTargetGlobal places the camera at the shoulder offset
+// instead of the avatar's eye position.
+// Avatar rendering is handled explicitly in needsRenderAvatar() and needsRenderHead().
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraToOTS()
+{
+ if (mCameraMode != CAMERA_MODE_OTS)
+ {
+ // Inherit everything from mouselook: cursor lock, mouse capture,
+ // AGENT_CONTROL_MOUSELOOK flag, keyboard focus clear, etc.
+ changeCameraToMouselook(false);
+
+ // Override mCameraMode to OTS so position/focus calculations
+ // use the shoulder offset instead of the eye position.
+ mCameraMode = CAMERA_MODE_OTS;
+
+ // changeCameraToMouselook hid attachments via updateAttachmentVisibility
+ // with CAMERA_MODE_MOUSELOOK. Restore full visibility for OTS mode.
+ if (isAgentAvatarValid())
+ {
+ gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON);
+ }
+
+ // Start the camera animation LAST, after mCameraMode is OTS and after
+ // changeCameraToMouselook(false) has cleared mCameraAnimating via its
+ // animate=false branch. The rendered camera is still at the old
+ // (third-person) position this frame, so startCameraAnimation snapshots
+ // that as the start point and updateCamera lerps to the OTS shoulder
+ // target over ZoomTime seconds — matching the mouselook transition feel.
+ startCameraAnimation();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// changeCameraFromOTS()
+//-----------------------------------------------------------------------------
+void LLAgentCamera::changeCameraFromOTS()
+{
+ if (mCameraMode == CAMERA_MODE_OTS)
+ {
+ // changeCameraToDefault handles clearing AGENT_CONTROL_MOUSELOOK,
+ // showing the cursor, and restoring the normal camera mode.
+ changeCameraToDefault();
+ }
+}
+
+//-----------------------------------------------------------------------------
// changeCameraToFollow()
//-----------------------------------------------------------------------------
void LLAgentCamera::changeCameraToFollow(bool animate)
@@ -2336,7 +2414,7 @@ void LLAgentCamera::changeCameraToThirdPerson(bool animate)
}
mCameraLag.clearVec();
- if (mCameraMode == CAMERA_MODE_MOUSELOOK)
+ if (mCameraMode == CAMERA_MODE_MOUSELOOK || mCameraMode == CAMERA_MODE_OTS)
{
mCurrentCameraDistance = MIN_CAMERA_DISTANCE;
mTargetCameraDistance = MIN_CAMERA_DISTANCE;
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index d277fd6158..ac1a36a6c2 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -43,7 +43,8 @@ enum ECameraMode
CAMERA_MODE_THIRD_PERSON,
CAMERA_MODE_MOUSELOOK,
CAMERA_MODE_CUSTOMIZE_AVATAR,
- CAMERA_MODE_FOLLOW
+ CAMERA_MODE_FOLLOW,
+ CAMERA_MODE_OTS // Over-the-shoulder: mouselook input + third-person camera
};
/** Camera Presets for CAMERA_MODE_THIRD_PERSON */
@@ -93,10 +94,14 @@ public:
void changeCameraToThirdPerson(bool animate = true);
void changeCameraToCustomizeAvatar(); // Trigger transition animation
void changeCameraToFollow(bool animate = true); // Ventrella
+ void changeCameraToOTS(); // Over-the-shoulder aim mode
+ void changeCameraFromOTS(); // Exit OTS back to third person
bool cameraThirdPerson() const { return (mCameraMode == CAMERA_MODE_THIRD_PERSON && mLastCameraMode == CAMERA_MODE_THIRD_PERSON); }
- bool cameraMouselook() const { return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK); }
+ // Also true for OTS — reuses mouselook input and UI behaviour; camera position handled separately.
+ bool cameraMouselook() const { return (mCameraMode == CAMERA_MODE_MOUSELOOK && mLastCameraMode == CAMERA_MODE_MOUSELOOK) || mCameraMode == CAMERA_MODE_OTS; }
bool cameraCustomizeAvatar() const { return (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR /*&& !mCameraAnimating*/); }
bool cameraFollow() const { return (mCameraMode == CAMERA_MODE_FOLLOW && mLastCameraMode == CAMERA_MODE_FOLLOW); }
+ bool cameraOTS() const { return mCameraMode == CAMERA_MODE_OTS; }
ECameraMode getCameraMode() const { return mCameraMode; }
ECameraMode getLastCameraMode() const { return mLastCameraMode; }
void updateCamera(); // Call once per frame to update camera location/orientation
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index c74c0db08c..719447b920 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -136,10 +136,12 @@
#include "stringize.h"
#include "llcoros.h"
#include "llexception.h"
-#if !_M_ARM64 // !LL_LINUX
+#if defined(LL_CEF)
#include "cef/dullahan_version.h"
+#endif
+#if defined(LL_VLC)
#include "vlc/libvlc_version.h"
-#endif // LL_LINUX
+#endif
#if LL_DARWIN
#if LL_SDL
@@ -3517,7 +3519,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["VOICE_VERSION"] = LLTrans::getString("NotConnected");
}
-#if !_M_ARM64 // !LL_LINUX
+#if defined(LL_CEF)
std::ostringstream cef_ver_codec;
cef_ver_codec << "Dullahan: ";
cef_ver_codec << DULLAHAN_VERSION_MAJOR;
@@ -3547,7 +3549,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["LIBCEF_VERSION"] = "Undefined";
#endif
-#if !_M_ARM64 // !LL_LINUX
+#if defined(LL_VLC)
std::ostringstream vlc_ver_codec;
vlc_ver_codec << LIBVLC_VERSION_MAJOR;
vlc_ver_codec << ".";
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 5bbaed750c..728a8ef81e 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -131,16 +131,12 @@ int main( int argc, char **argv )
// install unexpected exception handler
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
-#ifdef __aarch64__
- setenv("LD_PRELOAD", APP_PLUGIN_DIR"/libcef.so", 1);
-#else
# if LL_LINUX
setenv("LD_PRELOAD", "libpthread.so.0 libGL.so.1", 1);
# else
setenv("LD_PRELOAD", "libpthread.so libGL.so.1", 1);
# endif
setenv("__GL_THREADED_OPTIMIZATIONS", "1", 0);
-#endif
bool ok = viewer_app_ptr->init();
if(!ok)
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index fb1426a235..c6b17fcb4e 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -34,6 +34,7 @@
#include "llnotifications.h"
#include "llnotificationsutil.h"
#include "roles_constants.h" // for GP_MEMBER_INVITE
+#include "llregionflags.h" // for ESTATE_ACCESS_BANNED_AGENT_ADD
#include "llagent.h"
#include "llappviewer.h" // for gLastVersionChannel
@@ -625,6 +626,34 @@ void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
}
// static
+void LLAvatarActions::estateKickAvatar(const LLUUID& id)
+{
+ LLAvatarName av_name;
+ LLSD payload;
+ payload["avatar_id"] = id;
+ LLSD args;
+ if (LLAvatarNameCache::get(id, &av_name))
+ {
+ args["EVIL_USER"] = av_name.getCompleteName();
+ }
+ LLNotificationsUtil::add("EstateKickUser", args, payload, handleEstateKickAvatar);
+}
+
+// static
+void LLAvatarActions::estateBanAvatar(const LLUUID& id)
+{
+ LLAvatarName av_name;
+ LLSD payload;
+ payload["avatar_id"] = id;
+ LLSD args;
+ if (LLAvatarNameCache::get(id, &av_name))
+ {
+ args["AVATAR_NAME"] = av_name.getCompleteName();
+ }
+ LLNotificationsUtil::add("EstateBanUser", args, payload, handleEstateBanAvatar);
+}
+
+// static
void LLAvatarActions::freeze(const LLUUID& id)
{
LLSD payload;
@@ -1425,6 +1454,62 @@ bool LLAvatarActions::handleEjectAvatar(const LLSD& notification, const LLSD& re
return false;
}
+bool LLAvatarActions::handleEstateKickAvatar(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("EstateOwnerMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null);
+ msg->nextBlock("MethodData");
+ msg->addString("Method", "kickestate");
+ msg->addUUID("Invoice", LLUUID::generateNewID());
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", avatar_id.asString());
+ gAgent.sendReliableMessage();
+ }
+ return false;
+}
+
+bool LLAvatarActions::handleEstateBanAvatar(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0)
+ {
+ LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+ LLMessageSystem* msg = gMessageSystem;
+ msg->newMessage("EstateOwnerMessage");
+ msg->nextBlockFast(_PREHASH_AgentData);
+ msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+ msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null);
+ msg->nextBlock("MethodData");
+ msg->addString("Method", "estateaccessdelta");
+ msg->addUUID("Invoice", LLUUID::generateNewID());
+
+ std::string buf;
+ gAgent.getID().toString(buf);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
+
+ buf = llformat("%u", (U32)ESTATE_ACCESS_BANNED_AGENT_ADD);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
+
+ avatar_id.toString(buf);
+ msg->nextBlock("ParamList");
+ msg->addString("Parameter", buf);
+
+ gAgent.sendReliableMessage();
+ }
+ return false;
+}
+
bool LLAvatarActions::handleFreeze(const LLSD& notification, const LLSD& response)
{
S32 option = LLNotification::getSelectedOption(notification, response);
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 1f5a42ed22..bc4eb6fa60 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -192,6 +192,10 @@ public:
static void freezeAvatar(const LLUUID& id);
static void ejectAvatar(const LLUUID& id, bool ban_enabled = false);
+
+ static void estateKickAvatar(const LLUUID& id);
+
+ static void estateBanAvatar(const LLUUID& id);
/**
* Kick avatar off grid
*/
@@ -263,6 +267,8 @@ private:
static bool handlePay(const LLSD& notification, const LLSD& response, LLUUID avatar_id);
static bool handleFreezeAvatar(const LLSD& notification, const LLSD& response);
static bool handleEjectAvatar(const LLSD& notification, const LLSD& response);
+ static bool handleEstateKickAvatar(const LLSD& notification, const LLSD& response);
+ static bool handleEstateBanAvatar(const LLSD& notification, const LLSD& response);
static bool handleKick(const LLSD& notification, const LLSD& response);
static bool handleFreeze(const LLSD& notification, const LLSD& response);
static bool handleUnfreeze(const LLSD& notification, const LLSD& response);
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 794ae4ad44..537ea28a4d 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -84,11 +84,14 @@ LLContextMenu* PeopleContextMenu::createMenu()
registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id));
registrar.add("Avatar.Freeze", boost::bind(&LLAvatarActions::freezeAvatar, id));
registrar.add("Avatar.Eject", boost::bind(&PeopleContextMenu::eject, this));
+ registrar.add("Avatar.EstateKick", boost::bind(&LLAvatarActions::estateKickAvatar, id));
+ registrar.add("Avatar.EstateBan", boost::bind(&LLAvatarActions::estateBanAvatar, id));
enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
enable_registrar.add("Avatar.CheckItem", boost::bind(&PeopleContextMenu::checkContextMenuItem, this, _2));
enable_registrar.add("Avatar.EnableFreezeEject", boost::bind(&PeopleContextMenu::enableFreezeEject, this, _2));
+ enable_registrar.add("Avatar.EnableEstateEjectBan", boost::bind(&PeopleContextMenu::enableEstateEjectBan, this, _2));
// create the context menu from the XUI
menu = createFromFile("menu_people_nearby.xml");
@@ -318,6 +321,17 @@ bool PeopleContextMenu::enableFreezeEject(const LLSD& userdata)
return new_value;
}
+bool PeopleContextMenu::enableEstateEjectBan(const LLSD& userdata)
+{
+ if (gAgent.getID() == mUUIDs.front() || mUUIDs.size() != 1)
+ return false;
+
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return false;
+ if (gAgent.isGodlike()) return true;
+ return region->getOwner() == gAgent.getID() || region->isEstateManager();
+}
+
void PeopleContextMenu::requestTeleport()
{
// boost::bind cannot recognize overloaded method LLAvatarActions::teleportRequest(),
@@ -419,6 +433,8 @@ void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
items.push_back(std::string("block_unblock"));
items.push_back(std::string("freeze"));
items.push_back(std::string("eject"));
+ items.push_back(std::string("estate_eject"));
+ items.push_back(std::string("estate_ban"));
}
hide_context_entries(menu, items, disabled_items);
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index ad38cebc31..ad6a26c645 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -47,6 +47,7 @@ private:
bool enableContextMenuItem(const LLSD& userdata);
bool checkContextMenuItem(const LLSD& userdata);
bool enableFreezeEject(const LLSD& userdata);
+ bool enableEstateEjectBan(const LLSD& userdata);
void offerTeleport();
void eject();
void startConference();
diff --git a/indra/newview/llquickprefs.cpp b/indra/newview/llquickprefs.cpp
index 800aa7abac..9e83857a15 100644
--- a/indra/newview/llquickprefs.cpp
+++ b/indra/newview/llquickprefs.cpp
@@ -26,6 +26,8 @@
#include "llquickprefs.h"
#include "llagent.h"
+#include "llagentcamera.h"
+#include "llcheckboxctrl.h"
#include "llsliderctrl.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
@@ -97,6 +99,14 @@ bool LLFloaterQuickPrefs::postBuild()
}
onRegionChanged(); // evaluate current region immediately
+ // OTS aim mode checkbox
+ mOTSEnabledCheck = getChild<LLCheckBoxCtrl>("ots_enabled");
+ if (mOTSEnabledCheck)
+ {
+ mOTSEnabledCheck->setCommitCallback(
+ boost::bind(&LLFloaterQuickPrefs::onOTSEnabledChanged, this));
+ }
+
return true;
}
@@ -203,3 +213,16 @@ void LLFloaterQuickPrefs::syncAvatarZOffsetFromPreferenceSetting()
F32 value = gSavedPerAccountSettings.getF32("AvatarHoverOffsetZ");
mAvatarZOffsetSlider->setValue(value, false); // false = no commit signal
}
+
+void LLFloaterQuickPrefs::onOTSEnabledChanged()
+{
+ if (mOTSEnabledCheck)
+ {
+ gSavedSettings.setBOOL("OTSEnabled", mOTSEnabledCheck->get());
+ // If currently in OTS mode and checkbox was unchecked, exit OTS
+ if (!mOTSEnabledCheck->get() && gAgentCamera.cameraOTS())
+ {
+ gAgentCamera.changeCameraFromOTS();
+ }
+ }
+}
diff --git a/indra/newview/llquickprefs.h b/indra/newview/llquickprefs.h
index 0ef56a4299..b90333831c 100644
--- a/indra/newview/llquickprefs.h
+++ b/indra/newview/llquickprefs.h
@@ -27,6 +27,7 @@
#include "llfloater.h"
class LLSliderCtrl;
+class LLCheckBoxCtrl;
class LLTextBox;
/**
@@ -76,6 +77,10 @@ private:
void syncAvatarZOffsetFromPreferenceSetting();
boost::signals2::connection mRegionChangedSlot;
+
+ // OTS over-the-shoulder aim
+ LLCheckBoxCtrl* mOTSEnabledCheck { nullptr };
+ void onOTSEnabledChanged();
};
#endif // LL_LLQUICKPREFS_H
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 7d97151e9d..59dc4319e1 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -280,6 +280,12 @@ static void update_tp_display(bool minimized)
F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
+
+ // Reuse the minimized-window path to suppress the teleport progress screen.
+ if (gSavedSettings.getBOOL("DisableTeleportScreens"))
+ {
+ minimized = true;
+ }
if (gAgent.getTeleportState() != LLAgent::TELEPORT_START && teleport_percent > 100.f)
{
// Give up. Don't keep the UI locked forever.
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6448dd6ba5..66ca722b88 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1826,7 +1826,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
if (plugin_basename == "media_plugin_cef")
{
launcher_name = "/compat/linux/usr/libexec/megapahit/SLPlugin";
- plugin_name = "/compat/linux/usr/lib/x86_64-linux-gnu/libmedia_plugin_cef.so";
+ plugin_name = "/compat/linux/usr/lib/x86_64-linux-gnu/megapahit/libmedia_plugin_cef.so";
}
#endif
@@ -1891,8 +1891,8 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
std::string plugin_dir = gDirUtilp->getLLPluginDir();
if (plugin_basename == "media_plugin_cef")
{
- plugin_dir = "/compat/linux/usr/lib/x86_64-linux-gnu";
- plugin_name = "/usr/lib/x86_64-linux-gnu/libmedia_plugin_cef.so";
+ plugin_dir = "/compat/linux/usr/lib/x86_64-linux-gnu/megapahit";
+ plugin_name = "/usr/lib/x86_64-linux-gnu/megapahit/libmedia_plugin_cef.so";
}
#else
const std::string plugin_dir = gDirUtilp->getLLPluginDir();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4632800e2d..1b1d703f38 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4065,6 +4065,44 @@ void handle_avatar_eject(const LLSD& avatar_id)
}
}
+void handle_avatar_estate_kick(const LLSD& avatar_id)
+{
+ LLUUID id = avatar_id.asUUID();
+ if (id.isNull())
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(
+ LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar) id = avatar->getID();
+ }
+ if (id.notNull())
+ {
+ LLAvatarActions::estateKickAvatar(id);
+ }
+}
+
+void handle_avatar_estate_ban(const LLSD& avatar_id)
+{
+ LLUUID id = avatar_id.asUUID();
+ if (id.isNull())
+ {
+ LLVOAvatar* avatar = find_avatar_from_object(
+ LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
+ if (avatar) id = avatar->getID();
+ }
+ if (id.notNull())
+ {
+ LLAvatarActions::estateBanAvatar(id);
+ }
+}
+
+bool enable_estate_eject_ban(const LLSD& avatar_id)
+{
+ LLViewerRegion* region = gAgent.getRegion();
+ if (!region) return false;
+ if (gAgent.isGodlike()) return true;
+ return region->getOwner() == gAgent.getID() || region->isEstateManager();
+}
+
bool my_profile_visible()
{
LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID);
@@ -4778,25 +4816,37 @@ class LLViewMouselook : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
+ // When OTS is enabled M toggles OTS mode (shoulder cam).
+ // When disabled M toggles normal first-person mouselook.
+ if (gSavedSettings.getBOOL("OTSEnabled"))
+ {
+ if (!gAgentCamera.cameraOTS())
+ {
+ gAgentCamera.changeCameraToOTS();
+ }
+ else
+ {
+ gAgentCamera.changeCameraFromOTS();
+ }
+ return true;
+ }
+
if (!gAgentCamera.cameraMouselook())
{
gAgentCamera.changeCameraToMouselook();
}
else
{
- // NaCl: Right-click + scroll wheel zoom in mouselook (ported from Firestorm).
- // If we were zoomed when the user toggles out of mouselook, restore the
- // normal (pre-zoom) FOV before switching back to the default camera.
+ // NaCl: restore FOV on mouselook exit
LLVector3 mlFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
F32 cameraAngle = gSavedSettings.getF32("CameraAngle");
if (mlFovValues.mV[VZ] > 0.0f)
{
- mlFovValues.mV[VY] = cameraAngle; // preserve last zoomed FOV
+ mlFovValues.mV[VY] = cameraAngle;
mlFovValues.mV[VZ] = 0.0f;
gSavedSettings.setVector3("_NACL_MLFovValues", mlFovValues);
- gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VX]); // restore normal FOV
+ gSavedSettings.setF32("CameraAngle", mlFovValues.mV[VX]);
}
- // NaCl End
gAgentCamera.changeCameraToDefault();
}
return true;
@@ -10346,6 +10396,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
+ commit.add("Avatar.EstateKick", boost::bind(&handle_avatar_estate_kick, _2));
+ commit.add("Avatar.EstateBan", boost::bind(&handle_avatar_estate_ban, _2));
+ enable.add("Avatar.EnableEstateEjectBan", boost::bind(&enable_estate_eject_ban, _2));
commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector));
view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index b8515fd92b..1c6544f3f9 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6120,11 +6120,18 @@ void process_teleport_local(LLMessageSystem *msg,void**)
}
gAgent.setPositionAgent(pos);
- gAgentCamera.slamLookAt(look_at);
+
+ bool keep_camera_local_tp = gSavedSettings.getBOOL("KeepCameraOnLocalTeleport");
+
+ if (!keep_camera_local_tp)
+ {
+ gAgentCamera.slamLookAt(look_at);
+ }
if ( !(gAgent.getTeleportKeepsLookAt() && LLViewerJoystick::getInstance()->getOverrideCamera()) )
{
- gAgentCamera.resetView(true, true);
+ // resetView still runs (cleanup); the false args just leave the camera alone.
+ gAgentCamera.resetView(!keep_camera_local_tp, !keep_camera_local_tp);
}
// send camera update to new region
diff --git a/indra/newview/skins/default/xui/en/floater_quick_prefs.xml b/indra/newview/skins/default/xui/en/floater_quick_prefs.xml
index 8b20fda6f5..f5bdcf2156 100644
--- a/indra/newview/skins/default/xui/en/floater_quick_prefs.xml
+++ b/indra/newview/skins/default/xui/en/floater_quick_prefs.xml
@@ -9,7 +9,7 @@
can_minimize="true"
can_close="true"
can_resize="false"
- height="96"
+ height="240"
width="320"
layout="topleft"
name="quick_prefs"
@@ -82,4 +82,128 @@
name="max_bandwidth"
tool_tip="Network bandwidth in Kbps (50 – 3000)" />
+ <view_border
+ follows="left|right"
+ layout="topleft"
+ left="2"
+ right="-2"
+ top_pad="10"
+ height="2"
+ name="ots_divider" />
+
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="5"
+ top_pad="6"
+ width="290"
+ text_color="EmphasisColor"
+ name="OTSLabel">
+ Over-the-Shoulder Cam:
+ </text>
+
+ <check_box
+ control_name="OTSEnabled"
+ follows="left|top"
+ height="16"
+ label="Use Over-The-Shoulder Cam"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ width="290"
+ name="ots_enabled"
+ tool_tip="When checked, M enters shoulder cam instead of first-person mouselook" />
+
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="6"
+ width="100"
+ name="OTSDistLabel">
+ Distance:
+ </text>
+
+ <slider
+ control_name="OTSCameraDistance"
+ decimal_digits="1"
+ can_edit_text="true"
+ follows="left|right|top"
+ height="16"
+ increment="0.1"
+ initial_value="3.0"
+ max_val="10.0"
+ min_val="1.0"
+ label_width="0"
+ layout="topleft"
+ left="110"
+ right="-10"
+ top_delta="-2"
+ name="ots_distance"
+ tool_tip="Camera distance behind avatar (1 – 10 m)" />
+
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ width="100"
+ name="OTSSideLabel">
+ Side offset:
+ </text>
+
+ <slider
+ control_name="OTSCameraSide"
+ decimal_digits="2"
+ can_edit_text="true"
+ follows="left|right|top"
+ height="16"
+ increment="0.05"
+ initial_value="-0.5"
+ max_val="1.0"
+ min_val="-1.0"
+ label_width="0"
+ layout="topleft"
+ left="110"
+ right="-10"
+ top_delta="-2"
+ name="ots_side"
+ tool_tip="Side offset: negative = right shoulder, positive = left shoulder" />
+
+ <text
+ type="string"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="10"
+ top_pad="4"
+ width="100"
+ name="OTSHeightLabel">
+ Height:
+ </text>
+
+ <slider
+ control_name="OTSCameraHeight"
+ decimal_digits="2"
+ can_edit_text="true"
+ follows="left|right|top"
+ height="16"
+ increment="0.05"
+ initial_value="0.5"
+ max_val="2.0"
+ min_val="0.0"
+ label_width="0"
+ layout="topleft"
+ left="110"
+ right="-10"
+ top_delta="-2"
+ name="ots_height"
+ tool_tip="Camera height above avatar root (0 – 2 m)" />
+
</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index fc4ffde947..f86e9160ed 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -90,6 +90,22 @@
function="Avatar.EnableFreezeEject"/>
</menu_item_call>
<menu_item_call
+ label="Estate Eject"
+ name="EstateEject...">
+ <menu_item_call.on_click
+ function="Avatar.EstateKick" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableEstateEjectBan"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Estate Ban"
+ name="EstateBan...">
+ <menu_item_call.on_click
+ function="Avatar.EstateBan" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableEstateEjectBan"/>
+ </menu_item_call>
+ <menu_item_call
label="Debug Textures"
name="Debug...">
<menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index b7a296bf31..8d73eee60a 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -169,4 +169,20 @@
<menu_item_call.on_visible
function="Avatar.EnableFreezeEject"/>
</menu_item_call>
+ <menu_item_call
+ label="Estate Eject"
+ name="estate_eject">
+ <menu_item_call.on_click
+ function="Avatar.EstateKick" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableEstateEjectBan"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Estate Ban"
+ name="estate_ban">
+ <menu_item_call.on_click
+ function="Avatar.EstateBan" />
+ <menu_item_call.on_visible
+ function="Avatar.EnableEstateEjectBan"/>
+ </menu_item_call>
</context_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index facf9b7e46..65f26d50e7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5404,6 +5404,18 @@ Kick [EVIL_USER] from this estate?
<notification
icon="alertmodal.tga"
+ name="EstateBanUser"
+ type="alertmodal">
+Ban [AVATAR_NAME] from this estate?
+ <tag>confirm</tag>
+ <usetemplate
+ name="okcancelbuttons"
+ notext="Cancel"
+ yestext="Ban"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="EstateChangeCovenant"
type="alertmodal">
Are you sure you want to change the Estate Covenant?
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
index eee55bd7bc..ad24451e24 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_move.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -9,317 +9,450 @@
name="move_panel"
top="1"
width="517">
- <icon
- follows="left|top"
- height="18"
- image_name="Cam_FreeCam_Off"
- layout="topleft"
- name="camera_icon"
- mouse_opaque="false"
- visible="true"
- width="18"
- left="30"
- top="10"/>
- <slider
- can_edit_text="true"
- control_name="CameraAngle"
- decimal_digits="2"
- follows="left|top"
- height="16"
- increment="0.025"
- initial_value="1.57"
- layout="topleft"
- label_width="100"
- label="View angle"
- left_pad="30"
- max_val="2.97"
- min_val="0.17"
- name="camera_fov"
- show_text="false"
- width="240" />
- <slider
- can_edit_text="true"
- control_name="CameraOffsetScale"
- decimal_digits="2"
- follows="left|top"
- height="16"
- increment="0.025"
- initial_value="1"
- layout="topleft"
- label="Distance"
+
+ <tab_container
+ name="move_view_tab_container"
+ enabled="true"
+ top_pad="0"
+ follows="left|top|right|bottom"
+ width="517"
+ height="408"
left_delta="0"
- label_width="100"
- max_val="3"
- min_val="0.5"
- name="camera_offset_scale"
- show_text="false"
- width="240"
- top_pad="5"/>
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- left="80"
- name="heading2"
- width="270"
- top_pad="5">
- Automatic position for:
- </text>
- <check_box
- control_name="EditCameraMovement"
- height="20"
- follows="left|top"
- label="Build/Edit"
+ tab_position="top"
+ tab_stop="false">
+
+ <!-- ── Move & View tab (existing content) ─────────────────────────── -->
+ <panel
+ label="Move &amp; View"
+ name="move_view_panel"
layout="topleft"
- left_delta="30"
- name="edit_camera_movement"
- tool_tip="Use automatic camera positioning when entering and exiting edit mode"
- width="280"
- top_pad="5" />
- <check_box
- control_name="AppearanceCameraMovement"
- follows="left|top"
- height="16"
- label="Appearance"
- layout="topleft"
- name="appearance_camera_movement"
- tool_tip="Use automatic camera positioning while in edit mode"
- width="242" />
- <icon
- follows="left|top"
- height="18"
- image_name="Move_Walk_Off"
- layout="topleft"
- name="avatar_icon"
- mouse_opaque="false"
- visible="true"
- width="18"
- top_pad="10"
- left="30" />
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left="78"
- name="keyboard_lbl"
- width="270"
- top_delta="2">
- Keyboard:
- </text>
- <check_box
- control_name="ArrowKeysAlwaysMove"
- follows="left|top"
- height="20"
- label="Arrow keys always move me while in chat"
- layout="topleft"
- left_delta="5"
- name="arrow_keys_move_avatar_check"
- width="237"
- top_pad="5"/>
- <check_box
- control_name="AllowTapTapHoldRun"
- follows="left|top"
- height="20"
- label="Tap-tap-hold to run"
- layout="topleft"
- left_delta="0"
- name="tap_tap_hold_to_run"
- width="237"
- top_pad="0"/>
- <check_box
- control_name="AutomaticFly"
- follows="left|top"
- height="20"
- label="Hold jump or crouch key to start or stop flying"
- layout="topleft"
- left_delta="0"
- name="automatic_fly"
- width="237"
- top_pad="0"/>
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left="78"
- name="mouse_lbl"
- width="270"
- top_pad="15">
- Mouse:
- </text>
- <check_box
- control_name="FirstPersonAvatarVisible"
- follows="left|top"
- height="20"
- label="Show me in Mouselook"
- layout="topleft"
- left_delta="5"
- name="first_person_avatar_visible"
- top_pad="5"
- width="256" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="15"
- layout="topleft"
- left_delta="3"
- name=" Mouse Sensitivity"
- top_pad="10"
- width="160"
- wrap="true">
- Mouselook mouse sensitivity:
- </text>
- <slider
- control_name="MouseSensitivity"
- follows="left|top"
- height="15"
- initial_value="2"
- layout="topleft"
- show_text="false"
- left_pad="0"
- max_val="15"
- name="mouse_sensitivity"
- top_delta="-1"
- width="115" />
- <check_box
- control_name="InvertMouse"
- height="16"
- label="Invert"
- layout="topleft"
- left_pad="2"
- name="invert_mouse"
- top_delta="0"
- width="128" />
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left="86"
- name="mouse_warp_lbl"
- width="150"
- top_pad="20">
- Mouse Warp:
- </text>
- <combo_box
- control_name="MouseWarpMode"
- height="23"
- layout="topleft"
- left_pad="10"
- top_delta="-6"
- name="mouse_warp_combo"
- tool_tip="Controls warping of the mouse to the center of the screen during alt-zoom and mouse look."
- width="200">
- <combo_box.item
- label="Automatic"
- name="0"
- value="0"/>
- <combo_box.item
- label="On"
- name="1"
- value="1"/>
- <combo_box.item
- label="Off"
- name="2"
- value="2"/>
- </combo_box>
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left="86"
- name="single_click_action_lbl"
- width="150"
- top_pad="12">
- Single click on land:
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_pad="10"
- top_delta="-6"
- name="single_click_action_combo"
- width="200">
- <combo_box.item
- label="No action"
- name="0"
- value="0"/>
- <combo_box.item
- label="Move to clicked point"
- name="1"
- value="1"/>
- <combo_box.commit_callback
- function="Pref.ClickActionChange"/>
- </combo_box>
- <text
- follows="left|top"
- type="string"
- length="1"
- height="10"
- layout="topleft"
- left="86"
- name="double_click_action_lbl"
- width="150"
- top_pad="12">
- Double click on land:
- </text>
- <combo_box
- height="23"
- layout="topleft"
- left_pad="10"
- top_delta="-6"
- name="double_click_action_combo"
- width="200">
- <combo_box.item
- label="No action"
- name="0"
- value="0"/>
- <combo_box.item
- label="Move to clicked point"
- name="1"
- value="1"/>
- <combo_box.item
- label="Teleport to clicked point"
- name="2"
- value="2"/>
- <combo_box.commit_callback
- function="Pref.ClickActionChange"/>
- </combo_box>
- <check_box
- control_name="EnableCollisionSounds"
- height="20"
- label="Play sound on collisions"
- layout="topleft"
- left="83"
- name="sound_on_collisions"
- top_pad="0"
- width="200" />
- <check_box
- control_name="DoubleClickZoomIn"
- height="20"
- label="Double click on nearby list to zoom in on avatar"
- layout="topleft"
- left="83"
- name="double_click_zoom_in"
- top_pad="0"
- width="200" />
- <button
- height="23"
- label="Other Devices"
- left="30"
- name="joystick_setup_button"
- top="30"
- width="155">
- <button.commit_callback
- function="Floater.Show"
- parameter="pref_joystick" />
- </button>
+ follows="top|left">
+
+ <icon
+ follows="left|top"
+ height="18"
+ image_name="Cam_FreeCam_Off"
+ layout="topleft"
+ name="camera_icon"
+ mouse_opaque="false"
+ visible="true"
+ width="18"
+ left="30"
+ top="10"/>
+ <slider
+ can_edit_text="true"
+ control_name="CameraAngle"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="1.57"
+ layout="topleft"
+ label_width="100"
+ label="View angle"
+ left_pad="30"
+ max_val="2.97"
+ min_val="0.17"
+ name="camera_fov"
+ show_text="false"
+ width="240" />
+ <slider
+ can_edit_text="true"
+ control_name="CameraOffsetScale"
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.025"
+ initial_value="1"
+ layout="topleft"
+ label="Distance"
+ left_delta="0"
+ label_width="100"
+ max_val="3"
+ min_val="0.5"
+ name="camera_offset_scale"
+ show_text="false"
+ width="240"
+ top_pad="5"/>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ left="80"
+ name="heading2"
+ width="270"
+ top_pad="5">
+ Automatic position for:
+ </text>
+ <check_box
+ control_name="EditCameraMovement"
+ height="20"
+ follows="left|top"
+ label="Build/Edit"
+ layout="topleft"
+ left_delta="30"
+ name="edit_camera_movement"
+ tool_tip="Use automatic camera positioning when entering and exiting edit mode"
+ width="280"
+ top_pad="5" />
+ <check_box
+ control_name="AppearanceCameraMovement"
+ follows="left|top"
+ height="16"
+ label="Appearance"
+ layout="topleft"
+ name="appearance_camera_movement"
+ tool_tip="Use automatic camera positioning while in edit mode"
+ width="242" />
+ <icon
+ follows="left|top"
+ height="18"
+ image_name="Move_Walk_Off"
+ layout="topleft"
+ name="avatar_icon"
+ mouse_opaque="false"
+ visible="true"
+ width="18"
+ top_pad="10"
+ left="30" />
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="78"
+ name="keyboard_lbl"
+ width="270"
+ top_delta="2">
+ Keyboard:
+ </text>
+ <check_box
+ control_name="ArrowKeysAlwaysMove"
+ follows="left|top"
+ height="20"
+ label="Arrow keys always move me while in chat"
+ layout="topleft"
+ left_delta="5"
+ name="arrow_keys_move_avatar_check"
+ width="237"
+ top_pad="5"/>
+ <check_box
+ control_name="AllowTapTapHoldRun"
+ follows="left|top"
+ height="20"
+ label="Tap-tap-hold to run"
+ layout="topleft"
+ left_delta="0"
+ name="tap_tap_hold_to_run"
+ width="237"
+ top_pad="0"/>
+ <check_box
+ control_name="AutomaticFly"
+ follows="left|top"
+ height="20"
+ label="Hold jump or crouch key to start or stop flying"
+ layout="topleft"
+ left_delta="0"
+ name="automatic_fly"
+ width="237"
+ top_pad="0"/>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="78"
+ name="mouse_lbl"
+ width="270"
+ top_pad="15">
+ Mouse:
+ </text>
+ <check_box
+ control_name="FirstPersonAvatarVisible"
+ follows="left|top"
+ height="20"
+ label="Show me in Mouselook"
+ layout="topleft"
+ left_delta="5"
+ name="first_person_avatar_visible"
+ top_pad="5"
+ width="256" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="15"
+ layout="topleft"
+ left_delta="3"
+ name=" Mouse Sensitivity"
+ top_pad="10"
+ width="160"
+ wrap="true">
+ Mouselook mouse sensitivity:
+ </text>
+ <slider
+ control_name="MouseSensitivity"
+ follows="left|top"
+ height="15"
+ initial_value="2"
+ layout="topleft"
+ show_text="false"
+ left_pad="0"
+ max_val="15"
+ name="mouse_sensitivity"
+ top_delta="-1"
+ width="115" />
+ <check_box
+ control_name="InvertMouse"
+ height="16"
+ label="Invert"
+ layout="topleft"
+ left_pad="2"
+ name="invert_mouse"
+ top_delta="0"
+ width="128" />
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="mouse_warp_lbl"
+ width="150"
+ top_pad="20">
+ Mouse Warp:
+ </text>
+ <combo_box
+ control_name="MouseWarpMode"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="mouse_warp_combo"
+ tool_tip="Controls warping of the mouse to the center of the screen during alt-zoom and mouse look."
+ width="200">
+ <combo_box.item label="Automatic" name="0" value="0"/>
+ <combo_box.item label="On" name="1" value="1"/>
+ <combo_box.item label="Off" name="2" value="2"/>
+ </combo_box>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="single_click_action_lbl"
+ width="150"
+ top_pad="12">
+ Single click on land:
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="single_click_action_combo"
+ width="200">
+ <combo_box.item label="No action" name="0" value="0"/>
+ <combo_box.item label="Move to clicked point" name="1" value="1"/>
+ <combo_box.commit_callback function="Pref.ClickActionChange"/>
+ </combo_box>
+ <text
+ follows="left|top"
+ type="string"
+ length="1"
+ height="10"
+ layout="topleft"
+ left="86"
+ name="double_click_action_lbl"
+ width="150"
+ top_pad="12">
+ Double click on land:
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="-6"
+ name="double_click_action_combo"
+ width="200">
+ <combo_box.item label="No action" name="0" value="0"/>
+ <combo_box.item label="Move to clicked point" name="1" value="1"/>
+ <combo_box.item label="Teleport to clicked point" name="2" value="2"/>
+ <combo_box.commit_callback function="Pref.ClickActionChange"/>
+ </combo_box>
+ <check_box
+ control_name="EnableCollisionSounds"
+ height="20"
+ label="Play sound on collisions"
+ layout="topleft"
+ left="83"
+ name="sound_on_collisions"
+ top_pad="0"
+ width="200" />
+ <check_box
+ control_name="DoubleClickZoomIn"
+ height="20"
+ label="Double click on nearby list to zoom in on avatar"
+ layout="topleft"
+ left="83"
+ name="double_click_zoom_in"
+ top_pad="0"
+ width="200" />
+ <button
+ height="23"
+ label="Other Devices"
+ left="30"
+ name="joystick_setup_button"
+ top="30"
+ width="155">
+ <button.commit_callback function="Floater.Show" parameter="pref_joystick" />
+ </button>
+
+ </panel>
+
+ <!-- ── Over-The-Shoulder tab ──────────────────────────────────────── -->
+ <panel
+ label="Over-The-Shoulder"
+ name="ots_panel"
+ layout="topleft"
+ follows="top|left">
+
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmallBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="ots_enable_header"
+ top="10"
+ width="490">
+ Over-the-Shoulder Camera
+ </text>
+
+ <check_box
+ control_name="OTSEnabled"
+ follows="left|top"
+ height="20"
+ label="Use Over-The-Shoulder Cam"
+ layout="topleft"
+ left="15"
+ name="ots_enabled_pref"
+ top_pad="5"
+ tool_tip="When checked, pressing M enters over-the-shoulder cam instead of first-person mouselook"
+ width="350" />
+
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmallBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="ots_pos_header"
+ top_pad="12"
+ width="490">
+ Camera Position
+ </text>
+
+ <text type="string" follows="left|top" height="16" layout="topleft"
+ left="15" top_pad="6" width="130" name="dist_label">Distance:</text>
+ <slider
+ control_name="OTSCameraDistance"
+ decimal_digits="1" can_edit_text="true"
+ follows="left|right|top" height="16"
+ increment="0.1" initial_value="3.0" max_val="10.0" min_val="1.0"
+ label_width="0" layout="topleft" left="150" right="-10" top_delta="-2"
+ name="ots_distance"
+ tool_tip="Camera distance behind avatar (1 – 10 m)" />
+
+ <text type="string" follows="left|top" height="16" layout="topleft"
+ left="15" top_pad="6" width="130" name="side_label">Side offset:</text>
+ <slider
+ control_name="OTSCameraSide"
+ decimal_digits="2" can_edit_text="true"
+ follows="left|right|top" height="16"
+ increment="0.05" initial_value="-0.5" max_val="1.0" min_val="-1.0"
+ label_width="0" layout="topleft" left="150" right="-10" top_delta="-2"
+ name="ots_side"
+ tool_tip="Side offset: negative = right shoulder, positive = left shoulder" />
+
+ <text type="string" follows="left|top" height="16" layout="topleft"
+ left="15" top_pad="6" width="130" name="height_label">Height:</text>
+ <slider
+ control_name="OTSCameraHeight"
+ decimal_digits="2" can_edit_text="true"
+ follows="left|right|top" height="16"
+ increment="0.05" initial_value="0.5" max_val="2.0" min_val="0.0"
+ label_width="0" layout="topleft" left="150" right="-10" top_delta="-2"
+ name="ots_height"
+ tool_tip="Camera height above avatar root (0 – 2 m)" />
+
+ <text type="string" follows="left|top" height="16" layout="topleft"
+ left="15" top_pad="6" width="130" name="focus_label">Focus distance:</text>
+ <slider
+ control_name="OTSFocusDistance"
+ decimal_digits="1" can_edit_text="true"
+ follows="left|right|top" height="16"
+ increment="0.5" initial_value="10.0" max_val="30.0" min_val="2.0"
+ label_width="0" layout="topleft" left="150" right="-10" top_delta="-2"
+ name="ots_focus_dist"
+ tool_tip="Focus point distance along camera forward axis (2 – 30 m)" />
+
+ </panel>
+
+ <!-- ── Teleports tab ──────────────────────────────────────────────── -->
+ <panel
+ label="Teleports"
+ name="teleports_panel"
+ layout="topleft"
+ follows="top|left">
+
+ <text
+ type="string"
+ follows="left|top"
+ font="SansSerifSmallBold"
+ height="20"
+ layout="topleft"
+ left="10"
+ name="teleport_header"
+ top="10"
+ width="490">
+ Teleport Options
+ </text>
+
+ <check_box
+ control_name="KeepCameraOnLocalTeleport"
+ follows="left|top"
+ height="20"
+ label="Keep camera position on local teleport"
+ layout="topleft"
+ left="15"
+ name="keep_camera_on_local_teleport"
+ top_pad="8"
+ tool_tip="When teleporting within the same region, do not reset the camera position or mode (stays in mouselook/over-the-shoulder)"
+ width="450" />
+
+ <check_box
+ control_name="DisableTeleportScreens"
+ follows="left|top"
+ height="20"
+ label="Disable teleport progress screen"
+ layout="topleft"
+ left="15"
+ name="disable_teleport_screens"
+ top_pad="6"
+ tool_tip="Do not show the fullscreen progress/black screen during teleports"
+ width="450" />
+
+ </panel>
+
+ </tab_container>
+
</panel>