mirror of
https://github.com/mangosfour/server.git
synced 2025-12-15 01:37:00 +00:00
[7228] Implement empty bag swap with equipped non-empty bag with items exchange.
Signed-off-by: VladimirMangos <vladimir@getmangos.com> More early checks and proper swap bank bags in patch. Correct error messages in fail case.
This commit is contained in:
parent
fdd8176d74
commit
160777848a
2 changed files with 212 additions and 147 deletions
|
|
@ -10050,31 +10050,19 @@ uint8 Player::CanBankItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *p
|
|||
|
||||
// in specific slot
|
||||
if( bag != NULL_BAG && slot != NULL_SLOT )
|
||||
{
|
||||
if( pProto->InventoryType == INVTYPE_BAG )
|
||||
{
|
||||
Bag *pBag = (Bag*)pItem;
|
||||
if( pBag )
|
||||
{
|
||||
if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
|
||||
{
|
||||
if (!pItem->IsBag())
|
||||
return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
|
||||
|
||||
Bag *pBag = (Bag*)pItem;
|
||||
if( !HasBankBagSlot( slot ) )
|
||||
return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
|
||||
|
||||
if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
|
||||
return cantuse;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( !pBag->IsEmpty() )
|
||||
return EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END )
|
||||
return EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT;
|
||||
}
|
||||
|
||||
res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem);
|
||||
if(res!=EQUIP_ERR_OK)
|
||||
|
|
@ -11230,6 +11218,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
return;
|
||||
}
|
||||
|
||||
// SRC checks
|
||||
|
||||
if(pSrcItem->m_lootGenerated) // prevent swap looting item
|
||||
{
|
||||
//best error message found for attempting to swap while looting
|
||||
|
|
@ -11240,8 +11230,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
// check unequip potability for equipped items and bank bags
|
||||
if(IsEquipmentPos ( src ) || IsBagPos ( src ))
|
||||
{
|
||||
// bags can be swapped with empty bag slots
|
||||
uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ));
|
||||
// bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
|
||||
uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ) || pDstItem && pDstItem->IsBag() && ((Bag*)pDstItem)->IsEmpty());
|
||||
if(msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, pSrcItem, pDstItem );
|
||||
|
|
@ -11256,6 +11246,34 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
return;
|
||||
}
|
||||
|
||||
// DST checks
|
||||
|
||||
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 ))
|
||||
{
|
||||
// bags can be swapped with empty bag slots, or with empty bag (items move possibility checked later)
|
||||
uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) || pSrcItem->IsBag() && ((Bag*)pSrcItem)->IsEmpty());
|
||||
if(msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, pSrcItem, pDstItem );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
|
||||
// or swap empty bag with another empty or not empty bag (with items exchange)
|
||||
|
||||
// Move case
|
||||
if( !pDstItem )
|
||||
{
|
||||
if( IsInventoryPos( dst ) )
|
||||
|
|
@ -11298,29 +11316,12 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
EquipItem( dest, pSrcItem, true);
|
||||
AutoUnequipOffhandIfNeed();
|
||||
}
|
||||
}
|
||||
else // 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 ))
|
||||
{
|
||||
// bags can be swapped with empty bag slots
|
||||
uint8 msg = CanUnequipItem( dst, !IsBagPos ( dst ) || IsBagPos ( src ) );
|
||||
if(msg != EQUIP_ERR_OK)
|
||||
{
|
||||
SendEquipError( msg, pSrcItem, pDstItem );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// attempt merge to / fill target item
|
||||
if(!pSrcItem->IsBag() && !pDstItem->IsBag())
|
||||
{
|
||||
uint8 msg;
|
||||
ItemPosCountVec sDest;
|
||||
|
|
@ -11410,6 +11411,71 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
return;
|
||||
}
|
||||
|
||||
// Check bag swap with item exchange (one from empty in not bag possition (equipped (not possible in fact) or store)
|
||||
if(pSrcItem->IsBag() && pDstItem->IsBag())
|
||||
{
|
||||
Bag* emptyBag = NULL;
|
||||
Bag* fullBag = NULL;
|
||||
if(((Bag*)pSrcItem)->IsEmpty() && !IsBagPos(src))
|
||||
{
|
||||
emptyBag = (Bag*)pSrcItem;
|
||||
fullBag = (Bag*)pDstItem;
|
||||
}
|
||||
else if(((Bag*)pDstItem)->IsEmpty() && !IsBagPos(dst))
|
||||
{
|
||||
emptyBag = (Bag*)pDstItem;
|
||||
fullBag = (Bag*)pSrcItem;
|
||||
}
|
||||
|
||||
// bag swap (with items exchange) case
|
||||
if(emptyBag && fullBag)
|
||||
{
|
||||
ItemPrototype const* emotyProto = emptyBag->GetProto();
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
for(int i=0; i < fullBag->GetBagSize(); ++i)
|
||||
{
|
||||
Item *bagItem = fullBag->GetItemByPos(i);
|
||||
if (!bagItem)
|
||||
continue;
|
||||
|
||||
ItemPrototype const* bagItemProto = bagItem->GetProto();
|
||||
if (!bagItemProto || !ItemCanGoIntoBag(bagItemProto, emotyProto))
|
||||
{
|
||||
// one from items not go to empry target bag
|
||||
SendEquipError( EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG, pSrcItem, pDstItem );
|
||||
return;
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
|
||||
if (count > emptyBag->GetBagSize())
|
||||
{
|
||||
// too small targeted bag
|
||||
SendEquipError( EQUIP_ERR_ITEMS_CANT_BE_SWAPPED, pSrcItem, pDstItem );
|
||||
return;
|
||||
}
|
||||
|
||||
// Items swap
|
||||
count = 0; // will pos in new bag
|
||||
for(int i=0; i< fullBag->GetBagSize(); ++i)
|
||||
{
|
||||
Item *bagItem = fullBag->GetItemByPos(i);
|
||||
if (!bagItem)
|
||||
continue;
|
||||
|
||||
fullBag->RemoveItem(i, true);
|
||||
emptyBag->StoreItem(count, bagItem, true);
|
||||
bagItem->SetState(ITEM_CHANGED, this);
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now do moves, remove...
|
||||
RemoveItem(dstbag, dstslot, false);
|
||||
RemoveItem(srcbag, srcslot, false);
|
||||
|
|
@ -11432,7 +11498,6 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
|||
|
||||
AutoUnequipOffhandIfNeed();
|
||||
}
|
||||
}
|
||||
|
||||
void Player::AddItemToBuyBackSlot( Item *pItem )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "7227"
|
||||
#define REVISION_NR "7228"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue