From a31ce679f146da7eecaa6f6ea1e18349b64966b5 Mon Sep 17 00:00:00 2001 From: Fabien_HENON Date: Wed, 20 Jul 2011 22:09:01 +0200 Subject: [PATCH] Changed: #1304: Implementation of the "guild" parameter for the "destroy_item" action --- .../guild_manager/guild.cpp | 82 ++++++++++++++++ .../guild_manager/guild.h | 16 ++++ .../mission_manager/mission_action.cpp | 93 ++++++++++++++----- 3 files changed, 169 insertions(+), 22 deletions(-) diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp index df9082c6b..2460eb530 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp @@ -1030,6 +1030,88 @@ void CGuild::takeItem( CCharacter * user, uint32 slot, uint32 quantity, uint16 s } } +//---------------------------------------------------------------------------- +uint CGuild::selectItems(NLMISC::CSheetId itemSheetId, uint32 quality, std::vector *itemList) +{ + // For all items + uint quantitySelected= 0; + for (uint32 i = 0; i < _Inventory->getSlotCount(); i++) + { + CGameItemPtr item = _Inventory->getItem(i); + if (item == NULL) + continue; + + // if match, append to the list + if (item->getSheetId()==itemSheetId && item->quality()>=quality) + { + quantitySelected+= item->getStackSize(); + if(itemList) + { + CItemSlotId entry; + entry.Slot= i; + entry.Quality= item->quality(); + itemList->push_back(entry); + } + } + } + + return quantitySelected; +} + +//---------------------------------------------------------------------------- +uint CGuild::destroyItems(const std::vector &itemSlotIns, uint32 maxQuantity) +{ + // none to destroy actually? + if(maxQuantity==0 || itemSlotIns.empty()) + return 0; + + // If has to destroy only some of them, must sort to take first the ones of lowest quality + const std::vector *itemSlots= NULL; + std::vector itemSlotSorted; + if(maxQuantity!=uint32(-1)) + { + itemSlotSorted= itemSlotIns; + std::sort(itemSlotSorted.begin(), itemSlotSorted.end()); + itemSlots= &itemSlotSorted; + } + else + { + // just point to the original one + itemSlots= &itemSlotIns; + } + + // destroy items up to the maxquantity wanted + uint index= 0; + uint totalDestroyed= 0; + while(maxQuantity>0 && indexgetStackSize()); + + CGameItemPtr item = _Inventory->removeItem(itemSlot.Slot, quantityToDestroy); + item.deleteItem(); + + // decrease if not infinity + if(maxQuantity!=-1) + maxQuantity-= quantityToDestroy; + + // increase count + totalDestroyed+= quantityToDestroy; + } + + // next slot to destroy + index++; + } + + return totalDestroyed; +} + //---------------------------------------------------------------------------- void CGuild::takeMoney( CCharacter * user, uint64 money, uint16 session ) { diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild.h index 449debe53..671f7c17b 100644 --- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.h +++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.h @@ -237,6 +237,22 @@ public: /// add an item in the guild inventory (item can be deleted if not inserted : do not use it anymore in any case!) bool putItem( CGameItemPtr item ); + class CItemSlotId + { + public: + uint32 Slot; + uint32 Quality; + bool operator<(const CItemSlotId &o) const + { + return Quality *itemList= NULL); + /// destroy a list of items (up to maxQuantity to destroy) + uint destroyItems(const std::vector &itemSlots, uint32 maxQuantity=-1); + /// return the inventory (const) const NLMISC::CSmartPtr& getInventory() const { return _Inventory; } /// store for a character and return the current info version for an item of the guild inventory diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp index 5630913d0..bfb7c8d5a 100644 --- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp +++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp @@ -1270,32 +1270,81 @@ class CMissionActionDestroyItem : instance->getEntities(entities); if ( entities.empty() ) return; - for ( uint i = 0; i < entities.size(); i++ ) + + // If the "guild" parameter is not set, we destroy the items for the users + if (!_Guild) { - CCharacter * user = PlayerManager.getChar( entities[i] ); - if ( user ) + + for ( uint i = 0; i < entities.size(); i++ ) { - // Select the items in Bag AND mektoub that match the request - vector itemList; - user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList); - for(uint pa=0;paselectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList); + CCharacter * user = PlayerManager.getChar( entities[i] ); + if ( user ) + { + // Select the items in Bag AND mektoub that match the request + vector itemList; + user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList); + for(uint pa=0;paselectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList); - // Destroy them, up to quantity wanted - // NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near! - uint quantityReallyDestroyed; - quantityReallyDestroyed= user->destroyItems(itemList, _Quantity); + // Destroy them, up to quantity wanted + // NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near! + uint quantityReallyDestroyed; + quantityReallyDestroyed= user->destroyItems(itemList, _Quantity); - // Send message - SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer); - TAIAlias botAlias= _Npc; - if(botAlias==CAIAliasTranslator::Invalid) - botAlias= instance->getGiver(); - params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias); - params[1].SheetId = _SheetId; - params[2].Int = quantityReallyDestroyed; - params[3].Int = _Quality; - PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params); + // Send message + SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer); + TAIAlias botAlias= _Npc; + if(botAlias==CAIAliasTranslator::Invalid) + botAlias= instance->getGiver(); + params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias); + params[1].SheetId = _SheetId; + params[2].Int = quantityReallyDestroyed; + params[3].Int = _Quality; + PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params); + } + } + + } + // We destroy the item in the guild + else + { + CCharacter * user = PlayerManager.getChar( entities[0] ); + if (!user) + { + LOGMISSIONACTION("recv_fame : Invalid user"); + return; + } + + CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId()); + if (!guild) + { + LOGMISSIONACTION("recv_fame : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'"); + return; + } + + vector itemList; + guild->selectItems(_SheetId, _Quality, &itemList); + + // Destroy them, up to quantity wanted + uint quantityReallyDestroyed; + quantityReallyDestroyed = guild->destroyItems(itemList, _Quantity); + + // Send message + for ( uint i = 0; i < entities.size(); i++ ) + { + CCharacter * user = PlayerManager.getChar( entities[i] ); + if ( user ) + { + SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer); + TAIAlias botAlias= _Npc; + if(botAlias==CAIAliasTranslator::Invalid) + botAlias= instance->getGiver(); + params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias); + params[1].SheetId = _SheetId; + params[2].Int = quantityReallyDestroyed; + params[3].Int = _Quality; + PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params); + } } } };