Merged with default tip (Revision 0fd2a1181a96)

--HG--
branch : Appearance-Misc
master
Kitty Barnett 2011-08-06 15:19:24 +02:00
commit 3c7fb38745
16 changed files with 461 additions and 135 deletions

View File

@ -0,0 +1 @@
1fcbf79b59228a52b9c6c06609b9c2e58822f6e3

View File

@ -0,0 +1,27 @@
[Appearance/Misc]
- fixed : LLAppearanceMgr::filterWearableItems() doesn't properly filter body parts
- fixed : LLWearableList::processGetAssetReply() creates multiple LLWearable instances for the same asset UUID
-> fix for http://jira.secondlife.com/browse/VWR-20608
- fixed : attachments sometimes detach only to instantly get reattached after logon
- fixed : Add to/Replace Outfit removes newly worn attachments on completion
-> fix for http://jira.secondlife.com/browse/VWR-18512
- fixed : LLWearableBridge::removeAllClothesFromAvatar() doesn't remove all clothing from the avatar
- fixed : attachments that attach and then instantly detach don't have their COF link removed
- fixed : multiple LLWearableHoldingPattern instances lead to "COF corruption"
- fixed : get_is_item_worn() shouldn't make the assumption that items in COFs are always worn
- fixed : drag-and-drop wear behaviour of an attachment onto self isn't consistant with the drag-and-drop behaviour of wearables
-> normal-drop : replace wear
-> Ctrl-drop : add wear
- fixed : LLAppearanceMgr::registerAttachment() fails to (re)add a link for worn attachments that aren't linked to in COF at log-on
- fixed : LLViewerObject::getAttachmentItemID() sometimes returns the NULL UUID for the avatar's own attachments
- fixed : LLAppearanceMgr::updateAppearanceFromCOF() doesn't properly filter items collected from folder links
-> create an outfit with a folder link + "Replace Outfit" == wearables that exist in both COF and the linked folder will end up worn multiple times
- changed : deprecated removeItemFromAvatar() in favour of having LLAppearanceMgr::removeItemFromAvatar() handle it directly/correctly
-> wearables can't be worn/removed in 2.X without the viewer already having an LLWearable instance for it anyway
- changed : enable "Replace Current Outfit" on the base outfit if it's marked dirty
- changed : "RenderUnloadedAvatar" no longer affects the user's own avatar
-> side-effect of the fix above due to the change to LLVOAvatar::isFullyLoaded()
- added : InitialWearablesLoadedSignal signal which is emitted *once* when the initial wearables are loaded
- added : LegacyMultiAttachmentSupport debug setting to route "secondary attachment points" to the primary attachment point
-> maps secondary attachment point range [39,68] onto [1,30]
-> only dislays "secondary attachment points" correctly for *other* avatars (by design)

View File

@ -4689,6 +4689,17 @@
<key>Value</key>
<integer>0</integer>
</map>
<key>LegacyMultiAttachmentSupport</key>
<map>
<key>Comment</key>
<string>Converts legacy "secondary attachment points" to multi-attachments for other avatars</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
<key>LimitDragDistance</key>
<map>
<key>Comment</key>

View File

@ -55,6 +55,9 @@
LLAgentWearables gAgentWearables;
BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
bool LLAgentWearables::mInitialWearablesLoaded = false;
// [/SL:KB]
using namespace LLVOAvatarDefines;
@ -1448,6 +1451,13 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
// Start rendering & update the server
mWearablesLoaded = TRUE;
checkWearablesLoaded();
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-09-22 (Catznip-2.6.0a) | Modified: Catznip-2.2.0a
if (!mInitialWearablesLoaded)
{
mInitialWearablesLoaded = true;
mInitialWearablesLoadedSignal();
}
// [/SL:KB]
notifyLoadingFinished();
queryWearableCache();
updateServer();
@ -1725,7 +1735,10 @@ void LLAgentWearables::userRemoveAllClothesStep2(BOOL proceed)
// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
// get attachments into desired state with minimal number of adds/removes.
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
//void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly)
// [/SL:KB]
{
// Possible cases:
// already wearing but not in request set -> take off.
@ -1790,7 +1803,13 @@ void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj
// llinfos << "remove " << remove_count << " add " << add_count << llendl;
// Remove everything in objects_to_remove
userRemoveMultipleAttachments(objects_to_remove);
// userRemoveMultipleAttachments(objects_to_remove);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
if (!fAttachOnly)
{
userRemoveMultipleAttachments(objects_to_remove);
}
// [/SL:KB]
// Add everything in items_to_add
userAttachMultipleAttachments(items_to_add);
@ -2101,6 +2120,13 @@ boost::signals2::connection LLAgentWearables::addLoadedCallback(loaded_callback_
return mLoadedSignal.connect(cb);
}
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(loaded_callback_t cb)
{
return mInitialWearablesLoadedSignal.connect(cb);
}
// [/SL:KB]
void LLAgentWearables::notifyLoadingStarted()
{
mCOFChangeInProgress = true;

View File

@ -76,6 +76,9 @@ public:
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
BOOL areWearablesLoaded() const;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
bool areInitalWearablesLoaded() const { return mInitialWearablesLoaded; }
// [/SL:KB]
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
void updateWearablesLoaded();
void checkWearablesLoaded() const;
@ -215,7 +218,11 @@ public:
typedef std::vector<LLViewerObject*> llvo_vec_t;
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
// Not the best way to go about this but other attempts changed far too much LL code to be a viable solution
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
// [/SL:KB]
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
static void userRemoveAllAttachments();
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
@ -234,6 +241,9 @@ public:
typedef boost::function<void()> loaded_callback_t;
typedef boost::signals2::signal<void()> loaded_signal_t;
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
boost::signals2::connection addInitialWearablesLoadedCallback(loaded_callback_t cb);
// [/SL:KB]
void notifyLoadingStarted();
void notifyLoadingFinished();
@ -241,6 +251,9 @@ public:
private:
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
loaded_signal_t mInitialWearablesLoadedSignal; // emitted once when the initial wearables are loaded
// [/SL:KB]
//--------------------------------------------------------------------
// Member variables
@ -251,6 +264,9 @@ private:
wearableentry_map_t mWearableDatas;
static BOOL mInitialWearablesUpdateReceived;
// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
static bool mInitialWearablesLoaded;
// [/SL:KB]
BOOL mWearablesLoaded;
std::set<LLUUID> mItemsAwaitingWearableUpdate;

View File

@ -286,11 +286,15 @@ public:
void onWearableAssetFetch(LLWearable *wearable);
void onAllComplete();
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.6.0a) | Added: Catznip-2.0.0a
bool pollStopped();
// [/SL:KB]
typedef std::list<LLFoundData> found_list_t;
found_list_t& getFoundList();
void eraseTypeToLink(LLWearableType::EType type);
void eraseTypeToRecover(LLWearableType::EType type);
void setObjItems(const LLInventoryModel::item_array_t& items);
// void setObjItems(const LLInventoryModel::item_array_t& items);
void setGestItems(const LLInventoryModel::item_array_t& items);
bool isMostRecent();
void handleLateArrivals();
@ -298,7 +302,7 @@ public:
private:
found_list_t mFoundList;
LLInventoryModel::item_array_t mObjItems;
// LLInventoryModel::item_array_t mObjItems;
LLInventoryModel::item_array_t mGestItems;
typedef std::set<S32> type_set_t;
type_set_t mTypesToRecover;
@ -364,10 +368,15 @@ void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
mTypesToRecover.erase(type);
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-06-19 (Catznip-2.6.0a) | Added: Catznip-2.1.2a
// Fix for http://jira.secondlife.com/browse/VWR-18512
/*
void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
{
mObjItems = items;
}
*/
// [/SL:KB]
void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
{
@ -464,12 +473,17 @@ void LLWearableHoldingPattern::onAllComplete()
llinfos << "Updating agent wearables with " << mResolved << " wearable items " << llendl;
LLAppearanceMgr::instance().updateAgentWearables(this, false);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-03-22 (Catznip-2.6.0a) | Added: Catznip-2.1.2a
// Fix for http://jira.secondlife.com/browse/VWR-18512
/*
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
llinfos << "Updating " << mObjItems.count() << " attachments" << llendl;
LLAgentWearables::userUpdateAttachments(mObjItems);
}
*/
// [/SL:KB]
if (isFetchCompleted() && isMissingCompleted())
{
@ -499,6 +513,12 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
if (!isMostRecent())
{
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.6.0a) | Added: Catznip-2.0.0a
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
return true;
// [/SL:KB]
}
bool completed = isFetchCompleted();
@ -590,6 +610,11 @@ public:
if (!mHolder->isMostRecent())
{
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.6.0a) | Added: Catznip-2.0.0a
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
return;
// [/SL:KB]
}
llinfos << "Recovered item for type " << mType << llendl;
@ -664,11 +689,30 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
}
}
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.6.0a) | Added: Catznip-2.0.0a
bool LLWearableHoldingPattern::pollStopped()
{
// We have to keep on polling until we're sure that all callbacks have completed or they'll cause a crash
if ( (isFetchCompleted()) && (isMissingCompleted()) )
{
delete this;
return true;
}
return false;
}
// [/SL:KB]
bool LLWearableHoldingPattern::pollMissingWearables()
{
if (!isMostRecent())
{
llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.5.0a) | Added: Catznip-2.0.0a
// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
return true;
// [/SL:KB]
}
bool timed_out = isTimedOut();
@ -1301,7 +1345,10 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
}
// Check whether it's the base outfit.
if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
// if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.6.0a) | Added: Catznip-2.1.2d
if ( (outfit_cat_id.isNull()) || ((outfit_cat_id == getBaseOutfitUUID()) && (!isOutfitDirty())) )
// [/SL:KB]
{
return false;
}
@ -1374,7 +1421,11 @@ void LLAppearanceMgr::filterWearableItems(
S32 size = items_by_type[i].size();
if (size <= 0)
continue;
S32 start_index = llmax(0,size-max_per_type);
// S32 start_index = llmax(0,size-max_per_type);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.6.0a) | Added: Catznip-2.0.0h
S32 start_index =
llmax(0, size - ((LLAssetType::AT_BODYPART == LLWearableType::getAssetType((LLWearableType::EType)i)) ? 1 : max_per_type));
// [/SL:KB[
for (S32 j = start_index; j<size; j++)
{
items.push_back(items_by_type[i][j]);
@ -1702,10 +1753,45 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
remove_non_link_items(wear_items);
remove_non_link_items(obj_items);
remove_non_link_items(gest_items);
// [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-2.6.0a) | Added: Catzip-2.4.0f
// Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_PER_TYPE
removeDuplicateItems(wear_items);
removeDuplicateItems(obj_items);
removeDuplicateItems(gest_items);
filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_PER_TYPE);
// [/SL:KB]
dumpItemArray(wear_items,"asset_dump: wear_item");
dumpItemArray(obj_items,"asset_dump: obj_item");
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
// Update attachments to match those requested.
if (isAgentAvatarValid())
{
// Include attachments which should be in COF but don't have their link created yet
uuid_vec_t::iterator itPendingAttachLink = mPendingAttachLinks.begin();
while (itPendingAttachLink != mPendingAttachLinks.end())
{
const LLUUID& idItem = *itPendingAttachLink;
if ( (!gAgentAvatarp->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) )
{
itPendingAttachLink = mPendingAttachLinks.erase(itPendingAttachLink);
continue;
}
LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
if (pItem)
obj_items.push_back(pItem);
++itPendingAttachLink;
}
// Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on)
llinfos << "Updating " << obj_items.count() << " attachments" << llendl;
LLAgentWearables::userUpdateAttachments(obj_items, !gAgentAvatarp->isFullyLoaded());
}
// [/SL:KB]
if(!wear_items.count())
{
LLNotificationsUtil::add("CouldNotPutOnOutfit");
@ -1718,7 +1804,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
holder->setObjItems(obj_items);
// holder->setObjItems(obj_items);
holder->setGestItems(gest_items);
// Note: can't do normal iteration, because if all the
@ -2525,11 +2611,27 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
switch (item_to_remove->getType())
{
case LLAssetType::AT_CLOTHING:
if (get_is_item_worn(id_to_remove))
// if (get_is_item_worn(id_to_remove))
// {
// //*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
// LLWearableBridge::removeItemFromAvatar(item_to_remove);
// }
// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
{
//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
LLWearableBridge::removeItemFromAvatar(item_to_remove);
const LLWearable* pWearable = gAgentWearables.getWearableFromItemID(item_to_remove->getLinkedUUID());
if ( (pWearable) && (LLAssetType::AT_BODYPART != pWearable->getAssetType()) )
{
U32 idxWearable = gAgentWearables.getWearableIndex(pWearable);
if (idxWearable < LLAgentWearables::MAX_CLOTHING_PER_TYPE)
{
gAgentWearables.removeWearable(pWearable->getType(), false, idxWearable);
LLAppearanceMgr::instance().removeCOFItemLinks(item_to_remove->getLinkedUUID(), false);
gInventory.notifyObservers();
}
}
}
// [/SL:KB]
break;
case LLAssetType::AT_OBJECT:
LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
@ -2675,6 +2777,12 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
{
llinfos << "setAttachmentInvLinkEnable => " << (int) val << llendl;
mAttachmentInvLinkEnabled = val;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
if (mAttachmentInvLinkEnabled)
{
linkPendingAttachments();
}
// [/SL:KB]
}
void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
@ -2697,13 +2805,24 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
if (isLinkInCOF(item_id))
{
return;
}
mPendingAttachLinks.push_back(item_id);
// [/SL:KB]
if (mAttachmentInvLinkEnabled)
{
// we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF.
// it will trigger gAgentWariables.notifyLoadingFinished()
// But it is not acceptable solution. See EXT-7777
LLAppearanceMgr::addCOFItemLink(item_id, false); // Add COF link for item.
// LLAppearanceMgr::addCOFItemLink(item_id, false); // Add COF link for item.
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.6.0a) | Modified: Catznip-2.2.0a
LLPointer<LLInventoryCallback> cb = new LLRegisterAttachmentCallback();
LLAppearanceMgr::addCOFItemLink(item_id, false, cb); // Add COF link for item.
// [/SL:KB]
}
else
{
@ -2714,6 +2833,13 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
{
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-10-05 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
uuid_vec_t::iterator itPendingAttachLink = std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), item_id);
if (itPendingAttachLink != mPendingAttachLinks.end())
{
mPendingAttachLinks.erase(itPendingAttachLink);
}
// [/SL:KB]
if (mAttachmentInvLinkEnabled)
{
@ -2725,6 +2851,38 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
}
}
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-2.6.0a) | Modified: Catznip-2.2.0a
void LLAppearanceMgr::linkPendingAttachments()
{
LLPointer<LLInventoryCallback> cb = NULL;
for (uuid_vec_t::const_iterator itPendingAttachLink = mPendingAttachLinks.begin();
itPendingAttachLink != mPendingAttachLinks.end(); ++itPendingAttachLink)
{
const LLUUID& idAttachItem = *itPendingAttachLink;
if ( (gAgentAvatarp->isWearingAttachment(idAttachItem)) && (!isLinkInCOF(idAttachItem)) )
{
if (!cb)
cb = new LLRegisterAttachmentCallback();
LLAppearanceMgr::addCOFItemLink(idAttachItem, false, cb);
}
}
}
void LLAppearanceMgr::onRegisterAttachmentComplete(const LLUUID& idItem)
{
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
// Remove the attachment from the pending list
uuid_vec_t::iterator itPendingAttachLink = std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), idItemBase);
if (itPendingAttachLink != mPendingAttachLinks.end())
mPendingAttachLinks.erase(itPendingAttachLink);
// It may have been detached already in which case we should remove the COF link
if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) )
removeCOFItemLinks(idItemBase, false);
}
// [/SL:KB]
BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
{
return gInventory.isObjectDescendentOf(obj_id, getCOF());

View File

@ -217,6 +217,14 @@ private:
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-18 (Catznip-2.6.0a) | Modified: Catznip-2.1.2e
public:
void linkPendingAttachments();
void onRegisterAttachmentComplete(const LLUUID& idItem);
private:
uuid_vec_t mPendingAttachLinks;
// [/SL:KB]
//////////////////////////////////////////////////////////////////////////////////
// Item-specific convenience functions
public:
@ -243,6 +251,19 @@ private:
bool mUpdateBaseOrder;
};
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-08-31 (Catznip-2.6.0a) | Added: Catznip-2.1.2a
class LLRegisterAttachmentCallback : public LLInventoryCallback
{
public:
LLRegisterAttachmentCallback() {}
/*virtual*/ ~LLRegisterAttachmentCallback() {}
/*virtual*/ void fire(const LLUUID& idItem)
{
LLAppearanceMgr::instance().onRegisterAttachmentComplete(idItem);
}
};
// [/SL:KB]
#define SUPPORT_ENSEMBLES 0

View File

@ -2499,6 +2499,9 @@ void LLFolderBridge::folderOptionsMenu()
// BAP change once we're no longer treating regular categories as ensembles.
const bool is_ensemble = (type == LLFolderType::FT_NONE ||
LLFolderType::lookupIsEnsembleType(type));
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.6.0a) | Added: Catznip-2.4.0e
const bool is_outfit = (type == LLFolderType::FT_OUTFIT);
// [/SL:KB]
// Only enable calling-card related options for non-system folders.
if (!is_system_folder)
@ -2557,7 +2560,11 @@ void LLFolderBridge::folderOptionsMenu()
{
mDisabledItems.push_back(std::string("Remove From Outfit"));
}
if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
// if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.6.0a) | Added: Catznip-2.4.0e
if ( ((is_outfit) && (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))) ||
((!is_outfit) && (gAgentWearables.isCOFChangeInProgress())) )
// [/SL:KB]
{
mDisabledItems.push_back(std::string("Replace Outfit"));
}
@ -4544,11 +4551,14 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
continue;
if (get_is_item_worn(item->getUUID()))
{
LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
new OnRemoveStruct(item->getLinkedUUID()));
// 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.6.0a) | Added: Catznip-2.1.1d
LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID());
// [/SL:KB]
}
}
}
@ -4787,56 +4797,56 @@ void LLWearableBridge::wearAddOnAvatar()
}
// static
void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
{
LLViewerInventoryItem* item = NULL;
item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
if(item)
{
if(item->getAssetUUID() == wearable->getAssetID())
{
gAgentWearables.setWearableItem(item, wearable);
gInventory.notifyObservers();
//self->getFolderItem()->refreshFromRoot();
}
else
{
llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
}
}
}
delete item_id;
}
//void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
//{
// LLUUID* item_id = (LLUUID*) userdata;
// if(wearable)
// {
// LLViewerInventoryItem* item = NULL;
// item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
// if(item)
// {
// if(item->getAssetUUID() == wearable->getAssetID())
// {
// gAgentWearables.setWearableItem(item, wearable);
// gInventory.notifyObservers();
// //self->getFolderItem()->refreshFromRoot();
// }
// else
// {
// llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
// }
// }
// }
// delete item_id;
//}
// static
// BAP remove the "add" code path once everything is fully COF-ified.
void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
{
LLUUID* item_id = (LLUUID*) userdata;
if(wearable)
{
LLViewerInventoryItem* item = NULL;
item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
if(item)
{
if(item->getAssetUUID() == wearable->getAssetID())
{
bool do_append = true;
gAgentWearables.setWearableItem(item, wearable, do_append);
gInventory.notifyObservers();
//self->getFolderItem()->refreshFromRoot();
}
else
{
llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
}
}
}
delete item_id;
}
//void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
//{
// LLUUID* item_id = (LLUUID*) userdata;
// if(wearable)
// {
// LLViewerInventoryItem* item = NULL;
// item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
// if(item)
// {
// if(item->getAssetUUID() == wearable->getAssetID())
// {
// bool do_append = true;
// gAgentWearables.setWearableItem(item, wearable, do_append);
// gInventory.notifyObservers();
// //self->getFolderItem()->refreshFromRoot();
// }
// else
// {
// llinfos << "By the time wearable asset arrived, its inv item already pointed to a different asset." << llendl;
// }
// }
// }
// delete item_id;
//}
// static
BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
@ -4874,53 +4884,53 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
}
// static
void LLWearableBridge::onRemoveFromAvatar(void* user_data)
{
LLWearableBridge* self = (LLWearableBridge*)user_data;
if(!self) return;
if(get_is_item_worn(self->mUUID))
{
LLViewerInventoryItem* item = self->getItem();
if (item)
{
LLUUID parent_id = item->getParentUUID();
LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
onRemoveFromAvatarArrived,
new OnRemoveStruct(LLUUID(self->mUUID)));
}
}
}
//void LLWearableBridge::onRemoveFromAvatar(void* user_data)
//{
// LLWearableBridge* self = (LLWearableBridge*)user_data;
// if(!self) return;
// if(get_is_item_worn(self->mUUID))
// {
// LLViewerInventoryItem* item = self->getItem();
// if (item)
// {
// LLUUID parent_id = item->getParentUUID();
// LLWearableList::instance().getAsset(item->getAssetUUID(),
// item->getName(),
// item->getType(),
// onRemoveFromAvatarArrived,
// new OnRemoveStruct(LLUUID(self->mUUID)));
// }
// }
//}
// static
void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
void* userdata)
{
OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
if(wearable)
{
if( get_is_item_worn( item_id ) )
{
LLWearableType::EType type = wearable->getType();
if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&&
//!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) )
{
bool do_remove_all = false;
U32 index = gAgentWearables.getWearableIndex(wearable);
gAgentWearables.removeWearable( type, do_remove_all, index );
}
}
}
// Find and remove this item from the COF.
LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
gInventory.notifyObservers();
delete on_remove_struct;
}
//void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
// void* userdata)
//{
// OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
// const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
// if(wearable)
// {
// if( get_is_item_worn( item_id ) )
// {
// LLWearableType::EType type = wearable->getType();
//
// if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&&
// //!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) )
// {
// bool do_remove_all = false;
// U32 index = gAgentWearables.getWearableIndex(wearable);
// gAgentWearables.removeWearable( type, do_remove_all, index );
// }
// }
// }
//
// // Find and remove this item from the COF.
// LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
// gInventory.notifyObservers();
//
// delete on_remove_struct;
//}
// static
void LLWearableBridge::removeAllClothesFromAvatar()
@ -4931,7 +4941,10 @@ void LLWearableBridge::removeAllClothesFromAvatar()
if (itype == LLWearableType::WT_SHAPE || itype == LLWearableType::WT_SKIN || itype == LLWearableType::WT_HAIR || itype == LLWearableType::WT_EYES)
continue;
for (S32 index = gAgentWearables.getWearableCount(itype)-1; index >= 0 ; --index)
// for (S32 index = gAgentWearables.getWearableCount(itype)-1; index >= 0 ; --index)
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-04 (Catznip-2.6.0a) | Added: Catznip-2.1.2a
for (S32 index = gAgentWearables.getWearableCount((LLWearableType::EType)itype)-1; index >= 0 ; --index)
// [/SL:KB]
{
LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(
gAgentWearables.getWearableInventoryItem((LLWearableType::EType)itype, index));
@ -4957,11 +4970,14 @@ void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item)
{
if (item)
{
LLWearableList::instance().getAsset(item->getAssetUUID(),
item->getName(),
item->getType(),
LLWearableBridge::onRemoveFromAvatarArrived,
new OnRemoveStruct(item->getUUID()));
// LLWearableList::instance().getAsset(item->getAssetUUID(),
// item->getName(),
// item->getType(),
// LLWearableBridge::onRemoveFromAvatarArrived,
// new OnRemoveStruct(item->getUUID()));
// [SL:KB] - Patch: Appearance-RemoveWearableFromAvatar | Checked: 2010-08-13 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
LLAppearanceMgr::instance().removeItemFromAvatar(item->getUUID());
// [/SL:KB]
}
}

View File

@ -474,10 +474,10 @@ public:
static void onWearOnAvatar( void* userdata ); // Access to wearOnAvatar() from menu
static BOOL canWearOnAvatar( void* userdata );
static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
// static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
void wearOnAvatar();
static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
// static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
void wearAddOnAvatar();
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu
@ -485,8 +485,8 @@ public:
void editOnAvatar();
static BOOL canRemoveFromAvatar( void* userdata );
static void onRemoveFromAvatar( void* userdata );
static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
// static void onRemoveFromAvatar( void* userdata );
// static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
static void removeItemFromAvatar(LLViewerInventoryItem *item);
static void removeAllClothesFromAvatar();
void removeFromAvatar();

View File

@ -217,10 +217,11 @@ BOOL get_is_item_worn(const LLUUID& id)
return FALSE;
// Consider the item as worn if it has links in COF.
if (LLAppearanceMgr::instance().isLinkInCOF(id))
{
return TRUE;
}
// [SL:KB] - The code below causes problems across the board so it really just needs to go
// if (LLAppearanceMgr::instance().isLinkInCOF(id))
// {
// return TRUE;
// }
switch(item->getType())
{

View File

@ -1655,7 +1655,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
{
if(mSource == SOURCE_LIBRARY)
{
LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
// LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
// Make this behave consistent with dad3dWearItem
LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0, !(mask & MASK_CONTROL));
// [/SL:KB]
copy_inventory_item(
gAgent.getID(),
item->getPermissions().getOwner(),
@ -1666,7 +1670,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
}
else
{
rez_attachment(item, 0);
// rez_attachment(item, 0);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
// Make this behave consistent with dad3dWearItem
rez_attachment(item, 0, !(mask & MASK_CONTROL));
// [/SL:KB]
}
}
return ACCEPT_YES_SINGLE;

View File

@ -984,9 +984,13 @@ void ModifiedCOFCallback::fire(const LLUUID& inv_item)
}
}
RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
//RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace)
: mAttach(attachmentp), mReplace(replace)
// [/SL:KB]
{
mAttach = attachmentp;
// mAttach = attachmentp;
}
RezAttachmentCallback::~RezAttachmentCallback()
{
@ -1000,7 +1004,10 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)
LLViewerInventoryItem *item = gInventory.getItem(inv_item);
if (item)
{
rez_attachment(item, mAttach);
// rez_attachment(item, mAttach);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
rez_attachment(item, mAttach, mReplace);
// [/SL:KB]
}
}

View File

@ -263,7 +263,10 @@ class LLViewerJointAttachment;
class RezAttachmentCallback : public LLInventoryCallback
{
public:
RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
// RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
RezAttachmentCallback(LLViewerJointAttachment *attachmentp, bool replace = false);
// [/SL:KB]
void fire(const LLUUID& inv_item);
protected:
@ -271,6 +274,9 @@ protected:
private:
LLViewerJointAttachment* mAttach;
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-28 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
bool mReplace;
// [/SL:KB]
};
class ActivateGestureCallback : public LLInventoryCallback

View File

@ -158,7 +158,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
//-----------------------------------------------------------------------------
BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
{
object->extractAttachmentItemID();
// object->extractAttachmentItemID();
// Same object reattached
if (isObjectAttached(object))
@ -169,6 +169,11 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
// re-connect object to the joint correctly
}
// [SL:KB] - Patch: Appearance-Misc | Checked: Catznip-2.6.0a (2011-01-13) | Added: Catznip-2.4.0h
// LLViewerJointAttachment::removeObject() sets the object's item to the NULL UUID so we need to extract it *after* the block above
object->extractAttachmentItemID();
// [/SL:KB]
// Two instances of the same inventory item attached --
// Request detach, and kill the object in the meantime.
if (getAttachedObject(object->getAttachmentItemID()))

View File

@ -5955,7 +5955,13 @@ LLViewerJointAttachment* LLVOAvatar::getTargetAttachmentPoint(LLViewerObject* vi
if (!attachment)
{
llwarns << "Object attachment point invalid: " << attachmentID << llendl;
attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
// attachment = get_if_there(mAttachmentPoints, 1, (LLViewerJointAttachment*)NULL); // Arbitrary using 1 (chest)
// [SL:KB] - Patch: Appearance-LegacyMultiAttachment | Checked: 2010-08-28 (Catznip-2.6.0a) | Added: Catznip-2.1.2a
S32 idxAttachPt = 1;
if ( (!isSelf()) && (gSavedSettings.getBOOL("LegacyMultiAttachmentSupport")) && (attachmentID > 38) && (attachmentID <= 68) )
idxAttachPt = attachmentID - 38;
attachment = get_if_there(mAttachmentPoints, idxAttachPt, (LLViewerJointAttachment*)NULL);
// [/SL:KB]
}
return attachment;
@ -6471,10 +6477,17 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
BOOL LLVOAvatar::isFullyLoaded() const
{
if (gSavedSettings.getBOOL("RenderUnloadedAvatar"))
// if (gSavedSettings.getBOOL("RenderUnloadedAvatar"))
// return TRUE;
// else
// return mFullyLoaded;
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.6.0a) | Added: Catznip-2.2.0a
// Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp
if ( (!isSelf()) && (gSavedSettings.getBOOL("RenderUnloadedAvatar")) )
return TRUE;
else
return mFullyLoaded;
// [/SL:KB]
}

View File

@ -95,8 +95,18 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
{
BOOL isNewWearable = FALSE;
LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
LLWearable* wearable = NULL; // NULL indicates failure
// LLWearable* wearable = NULL; // NULL indicates failure
// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-08-13 (Catznip-2.6.0a) | Added: Catznip-2.1.1d
LLWearable* wearable = get_if_there(LLWearableList::instance().mList, uuid, (LLWearable*)NULL);
if (wearable)
{
if(data->mCallback)
data->mCallback(wearable, data->mUserdata);
delete data;
return;
}
// [/SL:KB]
if( !filename )
{
LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;