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
|
// in specific slot
|
||||||
if( bag != NULL_BAG && slot != NULL_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( 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 ) )
|
if( !HasBankBagSlot( slot ) )
|
||||||
return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
|
return EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT;
|
||||||
|
|
||||||
if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
|
if( uint8 cantuse = CanUseItem( pItem, not_loading ) != EQUIP_ERR_OK )
|
||||||
return cantuse;
|
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);
|
res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem);
|
||||||
if(res!=EQUIP_ERR_OK)
|
if(res!=EQUIP_ERR_OK)
|
||||||
|
|
@ -11230,6 +11218,8 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SRC checks
|
||||||
|
|
||||||
if(pSrcItem->m_lootGenerated) // prevent swap looting item
|
if(pSrcItem->m_lootGenerated) // prevent swap looting item
|
||||||
{
|
{
|
||||||
//best error message found for attempting to swap while looting
|
//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
|
// check unequip potability for equipped items and bank bags
|
||||||
if(IsEquipmentPos ( src ) || IsBagPos ( src ))
|
if(IsEquipmentPos ( src ) || IsBagPos ( src ))
|
||||||
{
|
{
|
||||||
// bags can be swapped with empty bag slots
|
// 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 ));
|
uint8 msg = CanUnequipItem( src, !IsBagPos ( src ) || IsBagPos ( dst ) || pDstItem && pDstItem->IsBag() && ((Bag*)pDstItem)->IsEmpty());
|
||||||
if(msg != EQUIP_ERR_OK)
|
if(msg != EQUIP_ERR_OK)
|
||||||
{
|
{
|
||||||
SendEquipError( msg, pSrcItem, pDstItem );
|
SendEquipError( msg, pSrcItem, pDstItem );
|
||||||
|
|
@ -11256,6 +11246,34 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
||||||
return;
|
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( !pDstItem )
|
||||||
{
|
{
|
||||||
if( IsInventoryPos( dst ) )
|
if( IsInventoryPos( dst ) )
|
||||||
|
|
@ -11298,29 +11316,12 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
||||||
EquipItem( dest, pSrcItem, true);
|
EquipItem( dest, pSrcItem, true);
|
||||||
AutoUnequipOffhandIfNeed();
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// attempt merge to / fill target item
|
// attempt merge to / fill target item
|
||||||
|
if(!pSrcItem->IsBag() && !pDstItem->IsBag())
|
||||||
{
|
{
|
||||||
uint8 msg;
|
uint8 msg;
|
||||||
ItemPosCountVec sDest;
|
ItemPosCountVec sDest;
|
||||||
|
|
@ -11410,6 +11411,71 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
||||||
return;
|
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...
|
// now do moves, remove...
|
||||||
RemoveItem(dstbag, dstslot, false);
|
RemoveItem(dstbag, dstslot, false);
|
||||||
RemoveItem(srcbag, srcslot, false);
|
RemoveItem(srcbag, srcslot, false);
|
||||||
|
|
@ -11432,7 +11498,6 @@ void Player::SwapItem( uint16 src, uint16 dst )
|
||||||
|
|
||||||
AutoUnequipOffhandIfNeed();
|
AutoUnequipOffhandIfNeed();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Player::AddItemToBuyBackSlot( Item *pItem )
|
void Player::AddItemToBuyBackSlot( Item *pItem )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7227"
|
#define REVISION_NR "7228"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue