Changed: #1304: Implementation of the "guild" parameter for the "destroy_item" action

--HG--
branch : gsoc2011-guildmissions
This commit is contained in:
Fabien_HENON 2011-07-20 22:09:01 +02:00
parent 757f393db1
commit 5762e00236
3 changed files with 169 additions and 22 deletions

View file

@ -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<CItemSlotId> *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<CItemSlotId> &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<CItemSlotId> *itemSlots= NULL;
std::vector<CItemSlotId> 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 && index<itemSlotIns.size())
{
const CItemSlotId &itemSlot= (*itemSlots)[index];
// locate the item
CGameItemPtr pItem= getItem(itemSlot.Slot);
if(pItem!=NULL)
{
// destroy
uint32 quantityToDestroy= maxQuantity;
quantityToDestroy= min(quantityToDestroy, pItem->getStackSize());
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 ) void CGuild::takeMoney( CCharacter * user, uint64 money, uint16 session )
{ {

View file

@ -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!) /// 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 ); bool putItem( CGameItemPtr item );
class CItemSlotId
{
public:
uint32 Slot;
uint32 Quality;
bool operator<(const CItemSlotId &o) const
{
return Quality<o.Quality;
}
};
/// check the presence of an item (or several items in a stack) by its sheetId/quality
uint selectItems(NLMISC::CSheetId itemSheetId, uint32 quality, std::vector<CItemSlotId> *itemList= NULL);
/// destroy a list of items (up to maxQuantity to destroy)
uint destroyItems(const std::vector<CItemSlotId> &itemSlots, uint32 maxQuantity=-1);
/// return the inventory (const) /// return the inventory (const)
const NLMISC::CSmartPtr<CGuildInventory>& getInventory() const { return _Inventory; } const NLMISC::CSmartPtr<CGuildInventory>& getInventory() const { return _Inventory; }
/// store for a character and return the current info version for an item of the guild inventory /// store for a character and return the current info version for an item of the guild inventory

View file

@ -1270,32 +1270,81 @@ class CMissionActionDestroyItem :
instance->getEntities(entities); instance->getEntities(entities);
if ( entities.empty() ) if ( entities.empty() )
return; 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 CCharacter * user = PlayerManager.getChar( entities[i] );
vector<CCharacter::CItemSlotId> itemList; if ( user )
user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList); {
for(uint pa=0;pa<INVENTORIES::max_pet_animal;pa++) // Select the items in Bag AND mektoub that match the request
user->selectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList); vector<CCharacter::CItemSlotId> itemList;
user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList);
for(uint pa=0;pa<INVENTORIES::max_pet_animal;pa++)
user->selectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList);
// Destroy them, up to quantity wanted // Destroy them, up to quantity wanted
// NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near! // NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near!
uint quantityReallyDestroyed; uint quantityReallyDestroyed;
quantityReallyDestroyed= user->destroyItems(itemList, _Quantity); quantityReallyDestroyed= user->destroyItems(itemList, _Quantity);
// Send message // Send message
SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer); SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
TAIAlias botAlias= _Npc; TAIAlias botAlias= _Npc;
if(botAlias==CAIAliasTranslator::Invalid) if(botAlias==CAIAliasTranslator::Invalid)
botAlias= instance->getGiver(); botAlias= instance->getGiver();
params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias); params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias);
params[1].SheetId = _SheetId; params[1].SheetId = _SheetId;
params[2].Int = quantityReallyDestroyed; params[2].Int = quantityReallyDestroyed;
params[3].Int = _Quality; params[3].Int = _Quality;
PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params); 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<CGuild::CItemSlotId> 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);
}
} }
} }
}; };