[9716] Allow to vendor have same items in list with different extanded price.

This commit is contained in:
VladimirMangos 2010-04-10 04:28:34 +04:00
parent da253087cb
commit 25c2a76b63
12 changed files with 56 additions and 33 deletions

View file

@ -58,29 +58,24 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
bool VendorItemData::RemoveItem( uint32 item_id )
{
bool found = false;
for(VendorItemList::iterator i = m_items.begin(); i != m_items.end(); ++i )
{
// can have many examples
if((*i)->item == item_id)
{
m_items.erase(i);
return true;
found = true;
}
}
return false;
return found;
}
size_t VendorItemData::FindItemSlot(uint32 item_id) const
{
for(size_t i = 0; i < m_items.size(); ++i )
if(m_items[i]->item == item_id)
return i;
return m_items.size();
}
VendorItem const* VendorItemData::FindItem(uint32 item_id) const
VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const
{
for(VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i )
if((*i)->item == item_id)
if((*i)->item == item_id && (*i)->ExtendedCost == extendedCost)
return *i;
return NULL;
}

View file

@ -301,8 +301,7 @@ struct VendorItemData
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost));
}
bool RemoveItem( uint32 item_id );
VendorItem const* FindItem(uint32 item_id) const;
size_t FindItemSlot(uint32 item_id) const;
VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const;
void Clear()
{

View file

@ -643,6 +643,11 @@ void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data )
recv_data >> vendorguid >> item >> slot >> bagguid >> bagslot >> count;
if (slot < 1)
return; // client numbering slots from 1
--slot;
uint8 bag = NULL_BAG; // init for case invalid bagGUID
// find bag slot by bag guid
@ -667,7 +672,7 @@ void WorldSession::HandleBuyItemInSlotOpcode( WorldPacket & recv_data )
if (bag == NULL_BAG)
return;
GetPlayer()->BuyItemFromVendor(vendorguid, item, count, bag, bagslot);
GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, bag, bagslot);
}
void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data )
@ -679,7 +684,12 @@ void WorldSession::HandleBuyItemOpcode( WorldPacket & recv_data )
recv_data >> vendorguid >> item >> slot >> count >> unk1;
GetPlayer()->BuyItemFromVendor(vendorguid, item, count, NULL_BAG, NULL_SLOT);
if (slot < 1)
return; // client numbering slots from 1
--slot;
GetPlayer()->BuyItemFromVendorSlot(vendorguid, slot, item, count, NULL_BAG, NULL_SLOT);
}
void WorldSession::HandleListInventoryOpcode( WorldPacket & recv_data )

View file

@ -8274,10 +8274,9 @@ bool ObjectMgr::RemoveVendorItem( uint32 entry,uint32 item )
if(iter == m_mCacheVendorItemMap.end())
return false;
if(!iter->second.FindItem(item))
if(!iter->second.RemoveItem(item))
return false;
iter->second.RemoveItem(item);
WorldDatabase.PExecuteLog("DELETE FROM npc_vendor WHERE entry='%u' AND item='%u'",entry, item);
return true;
}
@ -8348,12 +8347,12 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m
if(!vItems)
return true; // later checks for non-empty lists
if(vItems->FindItem(item_id))
if(vItems->FindItemCostPair(item_id,ExtendedCost))
{
if(pl)
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST,item_id);
ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost);
else
sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u for vendor (Entry: %u), ignoring", item_id, vendor_entry);
sLog.outErrorDb( "Table `npc_vendor` has duplicate items %u (with extended cost %u) for vendor (Entry: %u), ignoring", item_id, ExtendedCost, vendor_entry);
return false;
}

View file

@ -18296,7 +18296,7 @@ void Player::InitDisplayIds()
}
// Return true is the bought item has a max count to force refresh of window by caller
bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot)
bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot)
{
// cheating attempt
if (count < 1) count = 1;
@ -18326,14 +18326,19 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false;
}
size_t vendor_slot = vItems->FindItemSlot(item);
if (vendor_slot >= vItems->GetItemCount())
if (vendorslot >= vItems->GetItemCount())
{
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false;
}
VendorItem const* crItem = vItems->m_items[vendorslot];
if(!crItem || crItem->item != item) // store diff item (cheating)
{
SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0);
return false;
}
VendorItem const* crItem = vItems->m_items[vendor_slot];
// check current item amount if it limited
if (crItem->maxcount != 0)
@ -18435,7 +18440,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << uint64(pCreature->GetGUID());
data << uint32(vendor_slot+1); // numbered from 1 at client
data << uint32(vendorslot+1); // numbered from 1 at client
data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << uint32(count);
GetSession()->SendPacket(&data);
@ -18480,7 +18485,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4));
data << uint64(pCreature->GetGUID());
data << uint32(vendor_slot + 1); // numbered from 1 at client
data << uint32(vendorslot + 1); // numbered from 1 at client
data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF);
data << uint32(count);
GetSession()->SendPacket(&data);

View file

@ -1276,7 +1276,7 @@ class MANGOS_DLL_SPEC Player : public Unit
return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip();
}
void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );
bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint8 bag, uint8 slot);
bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot);
float GetReputationPriceDiscount( Creature const* pCreature ) const;
Player* GetTrader() const { return pTrader; }