//-TT Patch: "Wear Items" option in inventory to Replace Worn Items Only

- WIP
meow-7.2.2
Tozh 2011-03-08 08:15:44 -05:00
parent fde8adf516
commit 019a7687ae
9 changed files with 298 additions and 6 deletions

View File

@ -2121,6 +2121,12 @@ void LLAppearanceMgr::getUserDescendents(const LLUUID& category,
}
void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)
//-TT Patch: ReplaceWornItemsOnly
{
wearInventoryCategory(category, copy, append, false);
}
void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append, bool replace)
//-TT
{
if(!category) return;
@ -2132,9 +2138,26 @@ void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool
callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
&LLAppearanceMgr::instance(),
category->getUUID(), copy, append));
//-TT Patch: ReplaceWornItemsOnly
//category->getUUID(), copy, append, replace));
//-TT
}
//-TT Patch: ReplaceWornItemsOnly
void LLAppearanceMgr::replaceCategoryInCurrentOutfit(const LLUUID& cat_id)
{
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
wearInventoryCategory(cat, false, true);
}
//-TT
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
//-TT Patch: ReplaceWornItemsOnly
{
wearCategoryFinal(cat_id, copy_items, append, false);
}
void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append, bool replace)
//-TT
{
llinfos << "starting" << llendl;

View File

@ -62,8 +62,17 @@ public:
bool append = false, const LLUUID& idOutfit = LLUUID::null);
// [/RLVa:KB]
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
//-TT Patch: ReplaceWornItemsOnly
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append, bool items);
//-TT
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append);
//-TT Patch: ReplaceWornItemsOnly
void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append, bool items);
//-TT
//-TT Patch: ReplaceWornItemsOnly
void replaceCategoryInCurrentOutfit(const LLUUID& cat_id);
//-TT
void wearOutfitByName(const std::string& name);
void changeOutfit(bool proceed, const LLUUID& category, bool append);
void replaceCurrentOutfit(const LLUUID& new_outfit);

View File

@ -717,7 +717,7 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
sChildrenWidths[--index] = info_btn_width;
sChildrenWidths[--index] = profile_btn_width;
sChildrenWidths[--index] = speaking_indicator_width;
llassert(index == 0);
//llassert(index == 0);
}
void LLAvatarListItem::updateChildren()

View File

@ -494,6 +494,10 @@ void LLBottomTray::updateContextMenu(S32 x, S32 y, MASK mask)
mBottomTrayContextMenu->setItemVisible("NearbyChatBar_Delete", in_edit_box);
mBottomTrayContextMenu->setItemVisible("NearbyChatBar_Select_All", in_edit_box);
}
//void LLBottomTray::showVoiceButton(BOOL visible)
//{
// setTrayButtonVisibleIfPossible(RS_BUTTON_SPEAK, visible);
//}
void LLBottomTray::showGestureButton(BOOL visible)
{

View File

@ -111,6 +111,7 @@ public:
void showBottomTrayContextMenu(S32 x, S32 y, MASK mask);
//void showVoiceButton(BOOL visible);
void showGestureButton(BOOL visible);
void showMoveButton(BOOL visible);
void showCameraButton(BOOL visible);

View File

@ -104,6 +104,9 @@ void dec_busy_count()
// Function declarations
void remove_inventory_category_from_avatar(LLInventoryCategory* category);
void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
//-TT Patch: ReplaceWornItemsOnly
void wear_inventory_category_on_avatar(LLInventoryCategory* category, LLFolderView *fView);
//-TT
bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
void teleport_via_landmark(const LLUUID& asset_id);
@ -191,12 +194,12 @@ void LLInvFVBridge::cutToClipboard()
// *TODO: make sure this does the right thing
void LLInvFVBridge::showProperties()
{
show_item_profile(mUUID);
//show_item_profile(mUUID);
// Disable old properties floater; this is replaced by the sidepanel.
/*
/**/
//-TT Experiment.
LLFloaterReg::showInstance("properties", mUUID);
*/
}
void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
@ -2176,6 +2179,20 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
modifyOutfit(TRUE);
return;
}
//-TT Patch: ReplaceWornItemsOnly
else if ("replaceitems" == action)
{
LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLViewerInventoryCategory* cat = getCategory();
if(!cat) return;
wear_inventory_category_on_avatar ( cat, mRoot );
// modifyOutfit(TRUE, TRUE);
return;
}
//-TT
else if ("copy" == action)
{
copyToClipboard();
@ -2569,6 +2586,9 @@ void LLFolderBridge::folderOptionsMenu()
if (type != LLFolderType::FT_OUTFIT)
{
mItems.push_back(std::string("Add To Outfit"));
//-TT Patch: ReplaceWornItemsOnly
mItems.push_back(std::string("Wear Items"));
//-TT
}
mItems.push_back(std::string("Replace Outfit"));
}
@ -2938,13 +2958,20 @@ void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::ETyp
}
void LLFolderBridge::modifyOutfit(BOOL append)
//-TT Patch: ReplaceWornItemsOnly
{
modifyOutfit(append, false);
}
void LLFolderBridge::modifyOutfit(BOOL append, BOOL replace)
//-TT
{
LLInventoryModel* model = getInventoryModel();
if(!model) return;
LLViewerInventoryCategory* cat = getCategory();
if(!cat) return;
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append );
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append, replace );
}
// helper stuff
@ -4542,6 +4569,201 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory,
mInvType = inv_type;
}
//-TT Patch: ReplaceWornItemsOnly
// Collect all wearables, objects and gestures in the subtree, then wear them,
// replacing only relevant layers and attachment points
void wear_inventory_category_on_avatar(LLInventoryCategory* category, LLFolderView *fView)
{
if(!category) return;
llinfos << "ReplaceWornItemsOnly wear_inventory_category_on_avatar( " << category->getName()
<< " )" << llendl;
LLUUID category_id = category->getUUID();
// Find all the wearables that are in the category's subtree.
llinfos << "ReplaceWornItemsOnly find all wearables" << llendl;
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindWearables is_wearable;
gInventory.collectDescendentsIf(category_id,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_wearable);
S32 i;
S32 wearable_count = item_array.count();
LLInventoryModel::cat_array_t obj_cat_array;
LLInventoryModel::item_array_t obj_item_array;
LLIsType is_object( LLAssetType::AT_OBJECT );
gInventory.collectDescendentsIf(category_id,
obj_cat_array,
obj_item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_object);
S32 obj_count = obj_item_array.count();
// Find all gestures in this folder
LLInventoryModel::cat_array_t gest_cat_array;
LLInventoryModel::item_array_t gest_item_array;
LLIsType is_gesture( LLAssetType::AT_GESTURE );
gInventory.collectDescendentsIf(category_id,
gest_cat_array,
gest_item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_gesture);
S32 gest_count = gest_item_array.count();
if (wearable_count > 0) //Loop through wearables.
{
//llinfos << "ReplaceWornItemsOnly wearable_count" << wearable_count << llendl;
int aTypes[LLWearableType::WT_COUNT] = {0};
for(i = 0; i < wearable_count; ++i)
{
//llinfos << "ReplaceWornItemsOnly wearable_count loop, i=" << i << llendl;
LLViewerInventoryItem *item = item_array.get(i);
int iType = (int)item->getWearableType();
//llinfos << "ReplaceWornItemsOnly wearable_count loop, iType=" << iType << llendl;
if (item->isWearableType()
&& iType != LLWearableType::WT_INVALID
&& iType != LLWearableType::WT_NONE
&& !get_is_item_worn(item->getUUID())
)
{
/*
// [RLVa:KB] - Checked: 2010-04-04 (RLVa-1.2.0c) | Modified: RLVa-0.2.2a
if ( (rlv_handler_t::isEnabled()) && (!gRlvWearableLocks.canRemove(item)) )
continue;
// [/RLVa:KB]
LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
new OnRemoveStruct(item->getLinkedUUID()));
*/
// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-2.2.0a) | Added: Catznip-2.1.1d
aTypes[iType]++;
if (aTypes[iType] == 1) //first occurence of type, remove first
{
U32 count = gAgentWearables.getWearableCount((LLWearableType::EType)iType);
//llinfos << "Type: " << iType << " count " << count << llendl;
for (U32 j=0; j<count; j++) //remove all
{
//take the first one from the list, since the list is diminishing.
LLWearable* wearable = gAgentWearables.getWearable((LLWearableType::EType)iType,0);
//if the item is from our folder - don't remove it
//for (LLViewerInventoryItem *item = item_array.get(i);
if (item_array.find((LLViewerInventoryItem *)wearable) == -1)
LLAppearanceMgr::instance().removeItemFromAvatar(wearable->getItemID());
//llinfos << "Removing wearable name: " << wearable->getName() << llendl;
}
//now add the first item (replace just in case)
LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, true);
//llinfos << " Wearing item: " << item->getName() << " with replace=true" << llendl;
}
else // just add - unless it's body
{
if (!(iType == LLWearableType::WT_SHAPE) && !(iType == LLWearableType::WT_SKIN) &&
!(iType == LLWearableType::WT_HAIR) && !(iType == LLWearableType::WT_EYES))
LLAppearanceMgr::instance().wearItemOnAvatar(item->getUUID(), true, false);
}
}
}
}
if (obj_count > 0)
{
//all attachment points
//int oTypes[LLWearableType::WT_COUNT] = {0};
LLVOAvatar::attachment_map_t attachment_map;
//LLVector3 oTypes[obj_count] = {NULL};
for(i = 0; i < obj_count; ++i)
{
LLViewerInventoryItem *obj_item = obj_item_array.get(i);
//rez_attachment(item, NULL, true); // Replace if "Wear"ing.
////LLFolderViewItem* folder_item = fView->getItemByID(obj_item->getLinkedUUID());
////if(!folder_item) continue;
////LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
//////LLInvFVBridge* bridge = (LLInvFVBridge*)obj_item->getListener();
////if(!bridge) continue;
////bridge->performAction(&gInventory, "wear");
if (!get_is_item_worn(obj_item->getUUID()))
{
// first add the item without removing others
LLAppearanceMgr::instance().wearItemOnAvatar(obj_item->getUUID(), true, true);
//}
//}
////figure out where we added it
std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(obj_item->getUUID());
std::string attachment_point_name2 = gAgentAvatarp->getAttachedPointName(obj_item->getAssetUUID);
////S32 iCnt = gAgentAvatarp->getAttachmentCount();
////LLUUID attID = gAgentAvatarp->getAttachmentItemID();
//LLViewerJointAttachment *attPoint = gAgentAvatarp->getWornAttachmentPoint(obj_item->getUUID());
//std::string attName = attPoint->getName();
//
////check if there are other things on same point already
//S32 numCnt = attPoint->getNumObjects();
//if (numCnt > 1)
//{
// //attPoint->
// //gAgentAvatarp->clampAttachmentPositions();
// //LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
//}
////if any of those things aren't in our list - remove them
//if (attachment_point_name == LLStringUtil::null) // Error condition, invalid attach point
//{
// attachment_point_name = "Invalid Attachment";
//}
//llinfos << "attachment_point_name" << attachment_point_name << llendl;
//llinfos << "attName" << attName << llendl;
//llinfos << "numCnt" << numCnt << llendl;
////// e.g. "(worn on ...)" / "(attached to ...)"
////LLStringUtil::format_map_t args;
////args["[ATTACHMENT_POINT]"] = LLTrans::getString(attachment_point_name);
//LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
//LLVOAvatarSelf::attachObject(obj_item);
}
}
////ok, this is a kludge, but can we wait for the item to get attached
////in order to query where it got attached?
//for(i = 0; i < obj_count; ++i)
//{
// LLViewerInventoryItem *obj_item = obj_item_array.get(i);
// if (!get_is_item_worn(obj_item->getUUID()))
// {
// // first add the item without removing others
// LLAppearanceMgr::instance().wearItemOnAvatar(obj_item->getUUID(), true, false);
// }
//}
}
if (gest_count > 0)
{
for(i = 0; i < gest_count; ++i)
{
LLViewerInventoryItem *gest_item = gest_item_array.get(i);
if (get_is_item_worn(gest_item->getUUID()))
{
LLGestureMgr::instance().activateGesture( gest_item->getLinkedUUID() );
gInventory.updateItem( gest_item );
gInventory.notifyObservers();
}
}
}
}
//-TT
void remove_inventory_category_from_avatar( LLInventoryCategory* category )
{
if(!category) return;

View File

@ -291,6 +291,9 @@ protected:
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
void modifyOutfit(BOOL append);
//-TT Patch: ReplaceWornItemsOnly
void modifyOutfit(BOOL append, BOOL replace);
//-TT
void determineFolderType();
menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items

View File

@ -117,7 +117,9 @@ public:
registrar.add("Gear.Create", boost::bind(&LLOutfitListGearMenu::onCreate, this, _2));
registrar.add("Gear.WearAdd", boost::bind(&LLOutfitListGearMenu::onAdd, this));
//-TT Patch: ReplaceWornItemsOnly
registrar.add("Gear.WearReplaceItems",boost::bind(&LLOutfitListGearMenu::onReplaceItems, this));
//-TT
enable_registrar.add("Gear.OnEnable", boost::bind(&LLOutfitListGearMenu::onEnable, this, _2));
enable_registrar.add("Gear.OnVisible", boost::bind(&LLOutfitListGearMenu::onVisible, this, _2));
@ -186,6 +188,17 @@ private:
}
}
//-TT Patch: ReplaceWornItemsOnly
void onReplaceItems()
{
const LLUUID& selected_id = getSelectedOutfitID();
if (selected_id.notNull())
{
//LLAppearanceMgr::getInstance()->replaceCategoryInCurrentOutfit(selected_id);
}
}
//-TT
void onTakeOff()
{
// Take off selected outfit.
@ -279,6 +292,10 @@ protected:
boost::bind(&LLAppearanceMgr::replaceCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
registrar.add("Outfit.WearAdd",
boost::bind(&LLAppearanceMgr::addCategoryToCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
//-TT Patch: ReplaceWornItemsOnly
registrar.add("Outfit.WearReplaceItems",
boost::bind(&LLAppearanceMgr::replaceCategoryInCurrentOutfit, &LLAppearanceMgr::instance(), selected_id));
//-TT
registrar.add("Outfit.TakeOff",
boost::bind(&LLAppearanceMgr::takeOffOutfit, &LLAppearanceMgr::instance(), selected_id));
registrar.add("Outfit.Edit", boost::bind(editOutfit));
@ -626,6 +643,11 @@ void LLOutfitsList::performAction(std::string action)
{
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, FALSE );
}
if ("replaceitems" == action)
{
llinfos << "replaceitems" << llendl;
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE );
}
else if ("addtooutfit" == action)
{
LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, TRUE );

View File

@ -366,6 +366,14 @@
function="Inventory.DoToSelected"
parameter="addtooutfit" />
</menu_item_call>
<menu_item_call
label="Wear Items"
layout="topleft"
name="Wear Items">
<menu_item_call.on_click
function="Inventory.DoToSelected"
parameter="replaceitems" />
</menu_item_call>
<menu_item_call
label="Remove From Current Outfit"
layout="topleft"