RLVa impl updated to that used in v3. Hooked RLVa restrictions back into wearables. New RLVa floater: 'Locks...' Also updated 'Restrictions...' floater.
This commit is contained in:
@@ -227,7 +227,7 @@
|
||||
#include "llviewerregion.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llvolume.h"
|
||||
#include "llweb.h"
|
||||
#include "llworld.h"
|
||||
@@ -267,6 +267,8 @@ using namespace LLVOAvatarDefines;
|
||||
void init_client_menu(LLMenuGL* menu);
|
||||
void init_server_menu(LLMenuGL* menu);
|
||||
|
||||
typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
|
||||
|
||||
void init_debug_world_menu(LLMenuGL* menu);
|
||||
void init_debug_rendering_menu(LLMenuGL* menu);
|
||||
void init_debug_ui_menu(LLMenuGL* menu);
|
||||
@@ -275,6 +277,7 @@ void init_debug_avatar_menu(LLMenuGL* menu);
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvfloaterbehaviour.h"
|
||||
#include "rlvlocks.h"
|
||||
void init_debug_rlva_menu(LLMenuGL* menu);
|
||||
// [/RLVa:KB]
|
||||
|
||||
@@ -1186,7 +1189,7 @@ void init_client_menu(LLMenuGL* menu)
|
||||
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-1.0.0e | OK
|
||||
#ifdef RLV_ADVANCED_TOGGLE_RLVA
|
||||
if (gSavedSettings.controlExists(RLV_SETTING_MAIN))
|
||||
menu->addChild(new LLMenuItemCheckGL("RestrainedLove API", &rlvToggleEnabled, NULL, &rlvGetEnabled, NULL));
|
||||
menu->addChild(new LLMenuItemCheckGL("RestrainedLove API", &rlvMenuToggleEnabled, NULL, &rlvMenuCheckEnabled, NULL));
|
||||
#endif // RLV_ADVANCED_TOGGLE_RLVA
|
||||
// [/RLVa:KB]
|
||||
|
||||
@@ -1725,7 +1728,8 @@ void init_debug_rlva_menu(LLMenuGL* menu)
|
||||
|
||||
#ifdef RLV_EXTENSION_FLOATER_RESTRICTIONS
|
||||
// TODO-RLVa: figure out a way to tell if floater_rlv_behaviour.xml exists
|
||||
menu->addChild(new LLMenuItemCallGL("Restrictions...", RlvFloaterBehaviour::show, NULL, NULL));
|
||||
menu->addChild(new LLMenuItemCheckGL("Restrictions...", &RlvFloaterBehaviours::toggle, NULL, &RlvFloaterBehaviours::visible, NULL));
|
||||
menu->addChild(new LLMenuItemCheckGL("Locks...", &RlvFloaterLocks::toggle, NULL, &RlvFloaterLocks::visible, NULL));
|
||||
#endif // RLV_EXTENSION_FLOATER_RESTRICTIONS
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
@@ -2482,11 +2486,10 @@ class LLSelfEnableRemoveAllAttachments : public view_listener_t
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
bool new_value = false;
|
||||
if (gAgentAvatarp)
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
LLVOAvatar* avatarp = gAgentAvatarp;
|
||||
for (LLVOAvatar::attachment_map_t::iterator iter = avatarp->mAttachmentPoints.begin();
|
||||
iter != avatarp->mAttachmentPoints.end(); )
|
||||
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
iter != gAgentAvatarp->mAttachmentPoints.end(); )
|
||||
{
|
||||
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
||||
LLViewerJointAttachment* attachment = curiter->second;
|
||||
@@ -4582,22 +4585,21 @@ void handle_show_overlay_title(void*)
|
||||
gSavedSettings.setBOOL("ShowOverlayTitle", gShowOverlayTitle);
|
||||
}
|
||||
|
||||
void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
static bool get_derezzable_objects(
|
||||
EDeRezDestination dest,
|
||||
std::string& error,
|
||||
LLViewerRegion*& first_region,
|
||||
LLDynamicArray<LLViewerObjectPtr>* derez_objectsp,
|
||||
bool only_check = false)
|
||||
{
|
||||
if(gAgentCamera.cameraMouselook())
|
||||
{
|
||||
gAgentCamera.changeCameraToDefault();
|
||||
}
|
||||
//gInventoryView->setPanelOpen(TRUE);
|
||||
bool found = false;
|
||||
|
||||
std::string error;
|
||||
LLDynamicArray<LLViewerObject*> derez_objects;
|
||||
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
||||
|
||||
// Check conditions that we can't deal with, building a list of
|
||||
// everything that we'll actually be derezzing.
|
||||
LLViewerRegion* first_region = NULL;
|
||||
for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
|
||||
iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
|
||||
for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
|
||||
iter != selection->valid_root_end(); iter++)
|
||||
{
|
||||
LLSelectNode* node = *iter;
|
||||
LLViewerObject* object = node->getObject();
|
||||
@@ -4667,10 +4669,55 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
}
|
||||
if(can_derez_current)
|
||||
{
|
||||
derez_objects.put(object);
|
||||
found = true;
|
||||
|
||||
if (only_check)
|
||||
// one found, no need to traverse to the end
|
||||
break;
|
||||
|
||||
if (derez_objectsp)
|
||||
derez_objectsp->put(object);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static bool can_derez(EDeRezDestination dest)
|
||||
{
|
||||
LLViewerRegion* first_region = NULL;
|
||||
std::string error;
|
||||
return get_derezzable_objects(dest, error, first_region, NULL, true);
|
||||
}
|
||||
|
||||
static void derez_objects(
|
||||
EDeRezDestination dest,
|
||||
const LLUUID& dest_id,
|
||||
LLViewerRegion*& first_region,
|
||||
std::string& error,
|
||||
LLDynamicArray<LLViewerObjectPtr>* objectsp)
|
||||
{
|
||||
LLDynamicArray<LLViewerObjectPtr> derez_objects;
|
||||
|
||||
if (!objectsp) // if objects to derez not specified
|
||||
{
|
||||
// get them from selection
|
||||
if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false))
|
||||
{
|
||||
llwarns << "No objects to derez" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
objectsp = &derez_objects;
|
||||
}
|
||||
|
||||
|
||||
if(gAgentCamera.cameraMouselook())
|
||||
{
|
||||
gAgentCamera.changeCameraToDefault();
|
||||
}
|
||||
|
||||
// This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
|
||||
// root. I lopped off a few (33) to provide a bit
|
||||
// pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
|
||||
@@ -4678,13 +4725,13 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
// satisfy anybody.
|
||||
const S32 MAX_ROOTS_PER_PACKET = 250;
|
||||
const S32 MAX_PACKET_COUNT = 254;
|
||||
F32 packets = ceil((F32)derez_objects.count() / (F32)MAX_ROOTS_PER_PACKET);
|
||||
F32 packets = ceil((F32)objectsp->count() / (F32)MAX_ROOTS_PER_PACKET);
|
||||
if(packets > (F32)MAX_PACKET_COUNT)
|
||||
{
|
||||
error = "AcquireErrorTooManyObjects";
|
||||
}
|
||||
|
||||
if(error.empty() && derez_objects.count() > 0)
|
||||
if(error.empty() && objectsp->count() > 0)
|
||||
{
|
||||
U8 d = (U8)dest;
|
||||
LLUUID tid;
|
||||
@@ -4709,11 +4756,11 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
msg->addU8Fast(_PREHASH_PacketCount, packet_count);
|
||||
msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
|
||||
objects_in_packet = 0;
|
||||
while((object_index < derez_objects.count())
|
||||
while((object_index < objectsp->count())
|
||||
&& (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
|
||||
|
||||
{
|
||||
LLViewerObject* object = derez_objects.get(object_index++);
|
||||
LLViewerObject* object = objectsp->get(object_index++);
|
||||
msg->nextBlockFast(_PREHASH_ObjectData);
|
||||
msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
|
||||
// <edit>
|
||||
@@ -4741,19 +4788,31 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
}
|
||||
else if(!error.empty())
|
||||
{
|
||||
LLNotifications::instance().add(error);
|
||||
LLNotificationsUtil::add(error);
|
||||
}
|
||||
}
|
||||
|
||||
static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
||||
{
|
||||
LLViewerRegion* first_region = NULL;
|
||||
std::string error;
|
||||
derez_objects(dest, dest_id, first_region, error, NULL);
|
||||
}
|
||||
|
||||
class LLToolsTakeCopy : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
|
||||
// [RLVa:KB] - Checked: 2009-07-05 (RLVa-1.0.0b) | Modified: RLVa-1.0.0b | OK
|
||||
// NOTE: we need to handle "Take Copy" because it will force a sim-side unsit if we're sitting on the selection,
|
||||
// but we do want to allow "Take Copy" under @rez=n so that's why we explicitly check for @unsit=n here
|
||||
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (!rlvCanDeleteOrReturn()) ) return true;
|
||||
// [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
|
||||
if ( (rlv_handler_t::isEnabled()) && (!gRlvHandler.canStand()) )
|
||||
{
|
||||
// Allow only if the avie isn't sitting on any of the selected objects
|
||||
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
|
||||
RlvSelectIsSittingOn f(gAgentAvatarp);
|
||||
if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, TRUE) != NULL) )
|
||||
return true;
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
||||
@@ -4763,10 +4822,11 @@ class LLToolsTakeCopy : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// You can return an object to its owner if it is on your land.
|
||||
class LLObjectReturn : public view_listener_t
|
||||
{
|
||||
public:
|
||||
LLObjectReturn() : mFirstRegion(NULL) {}
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
|
||||
@@ -4776,26 +4836,36 @@ class LLObjectReturn : public view_listener_t
|
||||
|
||||
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
||||
|
||||
// Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
|
||||
get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects);
|
||||
|
||||
LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool onReturnToOwner(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (0 == option)
|
||||
{
|
||||
// Ignore category ID for this derez destination.
|
||||
derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null);
|
||||
derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects);
|
||||
}
|
||||
|
||||
mReturnableObjects.clear();
|
||||
mError.clear();
|
||||
mFirstRegion = NULL;
|
||||
|
||||
// drop reference to current selection
|
||||
mObjectSelection = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
LLObjectSelectionHandle mObjectSelection;
|
||||
|
||||
LLDynamicArray<LLViewerObjectPtr> mReturnableObjects;
|
||||
std::string mError;
|
||||
LLViewerRegion* mFirstRegion;
|
||||
};
|
||||
|
||||
|
||||
@@ -4805,6 +4875,17 @@ class LLObjectEnableReturn : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
||||
{
|
||||
// Do not enable if nothing selected
|
||||
return false;
|
||||
}
|
||||
// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a
|
||||
if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
#ifdef HACKED_GODLIKE_VIEWER
|
||||
bool new_value = true;
|
||||
#else
|
||||
@@ -4815,34 +4896,9 @@ class LLObjectEnableReturn : public view_listener_t
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region)
|
||||
{
|
||||
// Estate owners and managers can always return objects.
|
||||
if (region->canManageEstate())
|
||||
{
|
||||
new_value = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct f : public LLSelectedObjectFunctor
|
||||
{
|
||||
virtual bool apply(LLViewerObject* obj)
|
||||
{
|
||||
return (obj->isOverAgentOwnedLand() ||
|
||||
obj->isOverGroupOwnedLand() ||
|
||||
obj->permModify());
|
||||
}
|
||||
} func;
|
||||
const bool firstonly = true;
|
||||
new_value = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
|
||||
}
|
||||
}
|
||||
new_value = can_derez(DRD_RETURN_TO_OWNER);
|
||||
}
|
||||
#endif
|
||||
// [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.2.0e) | Modified: RLVa-1.0.0b | OK
|
||||
new_value &= (!rlv_handler_t::isEnabled()) || (rlvCanDeleteOrReturn());
|
||||
// [/RLVa:KB]
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
@@ -4915,8 +4971,7 @@ void handle_take()
|
||||
if(category_id.notNull())
|
||||
{
|
||||
// check trash
|
||||
LLUUID trash;
|
||||
trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
|
||||
{
|
||||
category_id.setNull();
|
||||
@@ -4968,7 +5023,7 @@ void handle_take()
|
||||
|
||||
bool confirm_take(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if(enable_take() && (option == 0))
|
||||
{
|
||||
derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
|
||||
@@ -5222,13 +5277,9 @@ BOOL sitting_on_selection()
|
||||
}
|
||||
|
||||
// Need to determine if avatar is sitting on this object
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if (!avatar)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (!isAgentAvatarValid()) return FALSE;
|
||||
|
||||
return (avatar->isSitting() && avatar->getRoot() == root_object);
|
||||
return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object);
|
||||
}
|
||||
|
||||
class LLToolsSaveToInventory : public view_listener_t
|
||||
@@ -5958,16 +6009,16 @@ class LLWorldAlwaysRun : public view_listener_t
|
||||
if (gAgent.getAlwaysRun())
|
||||
{
|
||||
gAgent.clearAlwaysRun();
|
||||
gAgent.clearRunning();
|
||||
// gAgent.clearRunning();
|
||||
}
|
||||
else
|
||||
{
|
||||
gAgent.setAlwaysRun();
|
||||
gAgent.setRunning();
|
||||
// gAgent.setRunning();
|
||||
}
|
||||
|
||||
// tell the simulator.
|
||||
gAgent.sendWalkRun(gAgent.getAlwaysRun());
|
||||
// gAgent.sendWalkRun(gAgent.getAlwaysRun());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -6136,6 +6187,10 @@ class LLToolsLookAtSelection : public view_listener_t
|
||||
}
|
||||
if (zoom)
|
||||
{
|
||||
// Make sure we are not increasing the distance between the camera and object
|
||||
LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
|
||||
distance = llmin(distance, (F32) orig_distance.length());
|
||||
|
||||
gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance),
|
||||
LLSelectMgr::getInstance()->getSelectionCenterGlobal(),
|
||||
object_id );
|
||||
@@ -6757,13 +6812,6 @@ class LLShowAgentProfile : public view_listener_t
|
||||
}
|
||||
else if (userdata.asString() == "hit object")
|
||||
{
|
||||
// [RLVa:KB] - Checked: 2009-07-08 (RLVa-1.0.0e)
|
||||
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (objectp)
|
||||
{
|
||||
@@ -6776,7 +6824,10 @@ class LLShowAgentProfile : public view_listener_t
|
||||
}
|
||||
|
||||
LLVOAvatar* avatar = find_avatar_from_object(agent_id);
|
||||
if (avatar)
|
||||
// if (avatar)
|
||||
// [RLVa:KB] - Checked: 2010-06-04 (RLVa-1.2.0d) | Modified: RLVa-1.2.0d
|
||||
if ( (avatar) && ((!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) || (gAgent.getID() == agent_id)) )
|
||||
// [/RLVa:KB]
|
||||
{
|
||||
LLFloaterAvatarInfo::show( avatar->getID() );
|
||||
}
|
||||
@@ -6901,6 +6952,7 @@ void handle_move(void*)
|
||||
class LLObjectAttachToAvatar : public view_listener_t
|
||||
{
|
||||
public:
|
||||
LLObjectAttachToAvatar(bool replace) : mReplace(replace) {}
|
||||
static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
|
||||
|
||||
private:
|
||||
@@ -6927,27 +6979,43 @@ private:
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
confirm_replace_attachment(0, attachment_point);
|
||||
confirmReplaceAttachment(0, attachment_point);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void onNearAttachObject(BOOL success, void *user_data);
|
||||
void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
|
||||
|
||||
struct CallbackData
|
||||
{
|
||||
CallbackData(LLViewerJointAttachment* point, bool replace) : mAttachmentPoint(point), mReplace(replace) {}
|
||||
|
||||
LLViewerJointAttachment* mAttachmentPoint;
|
||||
bool mReplace;
|
||||
};
|
||||
|
||||
protected:
|
||||
static LLObjectSelectionHandle sObjectSelection;
|
||||
bool mReplace;
|
||||
};
|
||||
|
||||
LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
|
||||
|
||||
void near_attach_object(BOOL success, void *user_data)
|
||||
// static
|
||||
void LLObjectAttachToAvatar::onNearAttachObject(BOOL success, void *user_data)
|
||||
{
|
||||
if (!user_data) return;
|
||||
CallbackData* cb_data = static_cast<CallbackData*>(user_data);
|
||||
|
||||
if (success)
|
||||
{
|
||||
LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
|
||||
const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint;
|
||||
|
||||
U8 attachment_id = 0;
|
||||
if (attachment)
|
||||
{
|
||||
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
|
||||
{
|
||||
if (iter->second == attachment)
|
||||
@@ -6962,12 +7030,15 @@ void near_attach_object(BOOL success, void *user_data)
|
||||
// interpret 0 as "default location"
|
||||
attachment_id = 0;
|
||||
}
|
||||
LLSelectMgr::getInstance()->sendAttach(attachment_id);
|
||||
LLSelectMgr::getInstance()->sendAttach(attachment_id, cb_data->mReplace);
|
||||
}
|
||||
LLObjectAttachToAvatar::setObjectSelection(NULL);
|
||||
|
||||
delete cb_data;
|
||||
}
|
||||
|
||||
void confirm_replace_attachment(S32 option, void* user_data)
|
||||
// static
|
||||
void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point)
|
||||
{
|
||||
if (option == 0/*YES*/)
|
||||
{
|
||||
@@ -6992,48 +7063,66 @@ void confirm_replace_attachment(S32 option, void* user_data)
|
||||
delta = delta * 0.5f;
|
||||
walkToSpot -= delta;
|
||||
|
||||
gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance);
|
||||
// The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak.
|
||||
CallbackData* user_data = new CallbackData(attachment_point, mReplace);
|
||||
gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance);
|
||||
gAgentCamera.clearFocusObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void callback_attachment_drop(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
// Ensure user confirmed the drop
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option != 0) return;
|
||||
|
||||
// Called when the user clicked on an object attached to them
|
||||
// and selected "Drop".
|
||||
LLUUID object_id = notification["payload"]["object_id"].asUUID();
|
||||
LLViewerObject *object = gObjectList.findObject(object_id);
|
||||
|
||||
if (!object)
|
||||
{
|
||||
llwarns << "handle_drop_attachment() - no object to drop" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
LLViewerObject *parent = (LLViewerObject*)object->getParent();
|
||||
while (parent)
|
||||
{
|
||||
if(parent->isAvatar())
|
||||
{
|
||||
break;
|
||||
}
|
||||
object = parent;
|
||||
parent = (LLViewerObject*)parent->getParent();
|
||||
}
|
||||
|
||||
if (!object)
|
||||
{
|
||||
llwarns << "handle_detach() - no object to detach" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (object->isAvatar())
|
||||
{
|
||||
llwarns << "Trying to detach avatar from avatar." << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
// reselect the object
|
||||
LLSelectMgr::getInstance()->selectObjectAndFamily(object);
|
||||
|
||||
LLSelectMgr::getInstance()->sendDropAttachment();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
class LLAttachmentDrop : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
// Called when the user clicked on an object attached to them
|
||||
// and selected "Drop".
|
||||
LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (!object)
|
||||
{
|
||||
llwarns << "handle_drop_attachment() - no object to drop" << llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
LLViewerObject *parent = (LLViewerObject*)object->getParent();
|
||||
while (parent)
|
||||
{
|
||||
if(parent->isAvatar())
|
||||
{
|
||||
break;
|
||||
}
|
||||
object = parent;
|
||||
parent = (LLViewerObject*)parent->getParent();
|
||||
}
|
||||
|
||||
if (!object)
|
||||
{
|
||||
llwarns << "handle_detach() - no object to detach" << llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (object->isAvatar())
|
||||
{
|
||||
llwarns << "Trying to detach avatar from avatar." << llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-03-15 (RLVa-1.2.0e) | Modified: RLVa-1.0.5 | OK
|
||||
if (rlv_handler_t::isEnabled())
|
||||
{
|
||||
@@ -7052,11 +7141,20 @@ class LLAttachmentDrop : public view_listener_t
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
// The sendDropAttachment() method works on the list of selected
|
||||
// objects. Thus we need to clear the list, make sure it only
|
||||
// contains the object the user clicked, send the message,
|
||||
// then clear the list.
|
||||
LLSelectMgr::getInstance()->sendDropAttachment();
|
||||
LLSD payload;
|
||||
LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
|
||||
if (object)
|
||||
{
|
||||
payload["object_id"] = object->getID();
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Drop object not found" << llendl;
|
||||
return true;
|
||||
}
|
||||
|
||||
LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -7334,6 +7432,8 @@ BOOL object_selected_and_point_valid(void *user_data)
|
||||
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f | OK
|
||||
if (rlv_handler_t::isEnabled())
|
||||
{
|
||||
if (!isAgentAvatarValid())
|
||||
return FALSE;
|
||||
// RELEASE-RLVa: look at the caller graph for this function on every new release
|
||||
// -> 1.22.11 and 1.23.4
|
||||
// - object_is_wearable() => dead code [user_data == NULL => default attach point => OK!]
|
||||
@@ -9155,6 +9255,22 @@ class LLEditTakeOff : public view_listener_t
|
||||
{
|
||||
// MULTI-WEARABLES: assuming user wanted to remove top shirt.
|
||||
U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-06-09 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
|
||||
if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearable(type)) )
|
||||
{
|
||||
// We'll use the first wearable we come across that can be removed (moving from top to bottom)
|
||||
for (; wearable_index >= 0; wearable_index--)
|
||||
{
|
||||
const LLWearable* pWearable = gAgentWearables.getWearable(type, wearable_index);
|
||||
if (!gRlvWearableLocks.isLockedWearable(pWearable))
|
||||
break;
|
||||
}
|
||||
if (wearable_index < 0)
|
||||
return true; // No wearable found that can be removed
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
|
||||
LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
|
||||
LLWearableBridge::removeItemFromAvatar(item);
|
||||
}
|
||||
@@ -9513,10 +9629,9 @@ void initialize_menus()
|
||||
addMenu(new LLObjectTouch(), "Object.Touch");
|
||||
addMenu(new LLObjectSitOrStand(), "Object.SitOrStand");
|
||||
addMenu(new LLObjectDelete(), "Object.Delete");
|
||||
addMenu(new LLObjectAttachToAvatar(), "Object.AttachToAvatar");
|
||||
addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
|
||||
addMenu(new LLObjectReturn(), "Object.Return");
|
||||
addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
|
||||
addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
|
||||
// <edit>
|
||||
addMenu(new LLObjectMeasure(), "Object.Measure");
|
||||
addMenu(new LLObjectData(), "Object.Data");
|
||||
|
||||
Reference in New Issue
Block a user