Skip to content

Commit

Permalink
[9227] More wide check item looting state at item operations.
Browse files Browse the repository at this point in the history
Move some checks from packet handlers to Player::Can functions

Patch base at idea suggested originally by zhenya.
  • Loading branch information
VladimirMangos committed Jan 21, 2010
1 parent 6919496 commit 5cf5f11
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 102 deletions.
20 changes: 20 additions & 0 deletions src/game/Item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,9 @@ bool Item::IsEquipped() const

bool Item::CanBeTraded(bool mail) const
{
if (m_lootGenerated)
return false;

if ((!mail || !IsBoundAccountWide()) && IsSoulBound())
return false;

Expand Down Expand Up @@ -1017,6 +1020,23 @@ void Item::BuildUpdateData(UpdateDataMapType& update_players)
ClearUpdateMask(false);
}

uint8 Item::CanBeMergedPartlyWith( ItemPrototype const* proto ) const
{
// check item type
if (GetEntry() != proto->ItemId)
return EQUIP_ERR_ITEM_CANT_STACK;

// check free space (full stacks can't be target of merge
if (GetCount() >= proto->GetMaxStackSize())
return EQUIP_ERR_ITEM_CANT_STACK;

// not allow merge looting currently items
if (m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED;

return EQUIP_ERR_OK;
}

bool ItemRequiredTarget::IsFitToRequirements( Unit* pUnitTarget ) const
{
if(pUnitTarget->GetTypeId() != TYPEID_UNIT)
Expand Down
1 change: 1 addition & 0 deletions src/game/Item.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class MANGOS_DLL_SPEC Item : public Object
uint32 GetMaxStackCount() const { return GetProto()->GetMaxStackSize(); }
uint8 GetGemCountWithID(uint32 GemID) const;
uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const;
uint8 CanBeMergedPartlyWith(ItemPrototype const* proto) const;

uint8 GetSlot() const {return m_slot;}
Bag *GetContainer() { return m_container; }
Expand Down
7 changes: 0 additions & 7 deletions src/game/ItemHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,6 @@ void WorldSession::HandleAutoEquipItemOpcode( WorldPacket & recv_data )
if( !pSrcItem )
return; // only at cheat

if(pSrcItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
_player->SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pSrcItem, NULL );
return;
}

uint16 dest;
uint8 msg = _player->CanEquipItem( NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag() );
if( msg != EQUIP_ERR_OK )
Expand Down
176 changes: 82 additions & 94 deletions src/game/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9033,13 +9033,10 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV
// non empty slot, check item type
else
{
// check item type
if (pItem2->GetEntry() != pProto->ItemId)
return EQUIP_ERR_ITEM_CANT_STACK;

// check free space
if (pItem2->GetCount() >= pProto->GetMaxStackSize())
return EQUIP_ERR_ITEM_CANT_STACK;
// can be merged at least partly
uint8 res = pItem2->CanBeMergedPartlyWith(pProto);
if (res != EQUIP_ERR_OK)
return res;

// free stack space or infinity
need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
Expand Down Expand Up @@ -9095,40 +9092,30 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy
if ((pItem2 != NULL) != merge)
continue;

uint32 need_space = pProto->GetMaxStackSize();

if (pItem2)
{
if (pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if(need_space > count)
need_space = count;

ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;
// can be merged at least partly
uint8 res = pItem2->CanBeMergedPartlyWith(pProto);
if (res != EQUIP_ERR_OK)
continue;

if (count==0)
return EQUIP_ERR_OK;
}
}
// descrease at current stacksize
need_space -= pItem2->GetCount();
}
else
{
uint32 need_space = pProto->GetMaxStackSize();
if (need_space > count)
need_space = count;

ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;
if (need_space > count)
need_space = count;

if (count==0)
return EQUIP_ERR_OK;
}
ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;

if (count==0)
return EQUIP_ERR_OK;
}
}
return EQUIP_ERR_OK;
Expand All @@ -9152,39 +9139,30 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end,
if ((pItem2 != NULL) != merge)
continue;

uint32 need_space = pProto->GetMaxStackSize();

if (pItem2)
{
if (pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize())
{
uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount();
if (need_space > count)
need_space = count;
ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;
// can be merged at least partly
uint8 res = pItem2->CanBeMergedPartlyWith(pProto);
if (res != EQUIP_ERR_OK)
continue;

if (count==0)
return EQUIP_ERR_OK;
}
}
// descrease at current stacksize
need_space -= pItem2->GetCount();
}
else
{
uint32 need_space = pProto->GetMaxStackSize();
if (need_space > count)
need_space = count;

ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;
if (need_space > count)
need_space = count;

if (count==0)
return EQUIP_ERR_OK;
}
ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space);
if (!newPosition.isContainedIn(dest))
{
dest.push_back(newPosition);
count -= need_space;

if (count==0)
return EQUIP_ERR_OK;
}
}
return EQUIP_ERR_OK;
Expand All @@ -9202,11 +9180,22 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND;
}

if (pItem && pItem->IsBindedNotWith(this))
if (pItem)
{
if (no_space_count)
*no_space_count = count;
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
// item used
if(pItem->m_lootGenerated)
{
if (no_space_count)
*no_space_count = count;
return EQUIP_ERR_ALREADY_LOOTED;
}

if (pItem->IsBindedNotWith(this))
{
if (no_space_count)
*no_space_count = count;
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
}
}

// check count of items (skip for auto move for same player from bank)
Expand Down Expand Up @@ -9684,6 +9673,10 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
if( !pProto )
return EQUIP_ERR_ITEM_NOT_FOUND;

// item used
if(pItem->m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED;

// item it 'bind'
if(pItem->IsBindedNotWith(this))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
Expand All @@ -9704,7 +9697,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(int t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
if( pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_keys[t-KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_keys[t-KEYRING_SLOT_START] += pItem->GetCount();
b_found = true;
Expand All @@ -9716,7 +9709,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
if( pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount();
b_found = true;
Expand All @@ -9728,7 +9721,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t)
{
pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t );
if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
if( pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_slot_items[t-INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_slot_items[t-INVENTORY_SLOT_ITEM_START] += pItem->GetCount();
b_found = true;
Expand All @@ -9745,7 +9738,7 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
{
pItem2 = GetItemByPos( t, j );
if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize())
if( pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_bags[t-INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize())
{
inv_bags[t-INVENTORY_SLOT_BAG_START][j] += pItem->GetCount();
b_found = true;
Expand Down Expand Up @@ -9887,6 +9880,10 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo
ItemPrototype const *pProto = pItem->GetProto();
if( pProto )
{
// item used
if(pItem->m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED;

if(pItem->IsBindedNotWith(this))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;

Expand Down Expand Up @@ -10030,6 +10027,10 @@ uint8 Player::CanUnequipItem( uint16 pos, bool swap ) const
if( !pProto )
return EQUIP_ERR_ITEM_NOT_FOUND;

// item used
if(pItem->m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED;

// do not allow unequipping gear except weapons, offhands, projectiles, relics in
// - combat
// - in-progress arenas
Expand All @@ -10054,16 +10055,17 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
if (!pItem)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;

if (pItem->m_lootGenerated)
return EQUIP_ERR_ITEM_LOCKED;

uint32 count = pItem->GetCount();

sLog.outDebug( "STORAGE: CanBankItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, pItem->GetEntry(), pItem->GetCount());
ItemPrototype const *pProto = pItem->GetProto();
if (!pProto)
return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_ITEM_NOT_FOUND;

// item used
if(pItem->m_lootGenerated)
return EQUIP_ERR_ALREADY_LOOTED;

if (pItem->IsBindedNotWith(this))
return EQUIP_ERR_DONT_OWN_THAT_ITEM;

Expand Down Expand Up @@ -11149,6 +11151,13 @@ void Player::SplitItem( uint16 src, uint16 dst, uint32 count )
return;
}

if(pSrcItem->m_lootGenerated) // prevent split looting item (item
{
//best error message found for attempting to split while looting
SendEquipError( EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL );
return;
}

// not let split all items (can be only at cheating)
if(pSrcItem->GetCount() == count)
{
Expand All @@ -11163,13 +11172,6 @@ void Player::SplitItem( uint16 src, uint16 dst, uint32 count )
return;
}

if(pSrcItem->m_lootGenerated) // prevent split looting item (item
{
//best error message found for attempting to split while looting
SendEquipError( EQUIP_ERR_COULDNT_SPLIT_ITEMS, pSrcItem, NULL );
return;
}

sLog.outDebug( "STORAGE: SplitItem bag = %u, slot = %u, item = %u, count = %u", dstbag, dstslot, pSrcItem->GetEntry(), count);
Item *pNewItem = pSrcItem->CloneItem( count, this );
if( !pNewItem )
Expand Down Expand Up @@ -11265,13 +11267,6 @@ void Player::SwapItem( uint16 src, uint16 dst )

// SRC checks

if (pSrcItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pSrcItem, NULL );
return;
}

// check unequip potability for equipped items and bank bags
if (IsEquipmentPos(src) || IsBagPos(src))
{
Expand Down Expand Up @@ -11302,13 +11297,6 @@ void Player::SwapItem( uint16 src, uint16 dst )

if (pDstItem)
{
if(pDstItem->m_lootGenerated) // prevent swap looting item
{
//best error message found for attempting to swap while looting
SendEquipError( EQUIP_ERR_CANT_DO_RIGHT_NOW, pDstItem, NULL );
return;
}

// check unequip potability for equipped items and bank bags
if(IsEquipmentPos ( dst ) || IsBagPos ( dst ))
{
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9226"
#define REVISION_NR "9227"
#endif // __REVISION_NR_H__

0 comments on commit 5cf5f11

Please sign in to comment.