diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 2b98d66eb..fe86b2c16 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -1072,14 +1072,16 @@ struct ItemDisplayInfoEntry // uint32 arenaseason; // arena season number(1-4) //}; +#define MAX_EXTENDED_COST_ITEMS 5 + struct ItemExtendedCostEntry { uint32 ID; // 0 extended-cost entry id uint32 reqhonorpoints; // 1 required honor points uint32 reqarenapoints; // 2 required arena points - uint32 reqarenaslot; // 4 arena slot restrctions (min slot value) - uint32 reqitem[5]; // 5-8 required item id - uint32 reqitemcount[5]; // 9-13 required count of 1st item + uint32 reqarenaslot; // 4 arena slot restrictions (min slot value) + uint32 reqitem[MAX_EXTENDED_COST_ITEMS]; // 5-8 required item id + uint32 reqitemcount[MAX_EXTENDED_COST_ITEMS]; // 9-13 required count of 1st item uint32 reqpersonalarenarating; // 14 required personal arena rating }; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fb362386d..f33cc9c7b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18818,6 +18818,22 @@ void Player::InitDisplayIds() } } +void Player::TakeExtendedCost(uint32 extendedCostId, uint32 count) +{ + ItemExtendedCostEntry const* extendedCost = sItemExtendedCostStore.LookupEntry(extendedCostId); + + if (extendedCost->reqhonorpoints) + ModifyHonorPoints(-int32(extendedCost->reqhonorpoints * count)); + if (extendedCost->reqarenapoints) + ModifyArenaPoints(-int32(extendedCost->reqarenapoints * count)); + + for (uint8 i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i) + { + if (extendedCost->reqitem[i]) + DestroyItemCount(extendedCost->reqitem[i], extendedCost->reqitemcount[i] * count, true); + } +} + // Return true is the bought item has a max count to force refresh of window by caller bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot) { @@ -18827,10 +18843,10 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin if (!isAlive()) return false; - ItemPrototype const *pProto = ObjectMgr::GetItemPrototype( item ); + ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(item); if (!pProto) { - SendBuyError( BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); + SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, item, 0); return false; } @@ -18846,7 +18862,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin VendorItemData const* tItems = pCreature->GetVendorTemplateItems(); if ((!vItems || vItems->Empty()) && (!tItems || tItems->Empty())) { - SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); + SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } @@ -18855,14 +18871,14 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin if (vendorslot >= vCount+tCount) { - SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); + SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } VendorItem const* crItem = vendorslot < vCount ? vItems->GetItem(vendorslot) : tItems->GetItem(vendorslot - vCount); if (!crItem) // store diff item (cheating) { - SendBuyError( BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); + SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } @@ -18874,28 +18890,30 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin ItemPrototype const* crProto = ObjectMgr::GetItemPrototype(crItem->item); if (crProto->Flags & ITEM_FLAG_BOA && crProto->RequiredReputationFaction && uint32(GetReputationRank(crProto->RequiredReputationFaction)) >= crProto->RequiredReputationRank) - converted = item == sObjectMgr.GetItemConvert(crItem->item, getRaceMask());; + converted = item == sObjectMgr.GetItemConvert(crItem->item, getRaceMask()); - if(!converted) + if (!converted) { SendBuyError(BUY_ERR_CANT_FIND_ITEM, pCreature, item, 0); return false; } } + uint32 totalCount = pProto->BuyCount * count; + // check current item amount if it limited if (crItem->maxcount != 0) { - if (pCreature->GetVendorItemCurrentCount(crItem) < pProto->BuyCount * count ) + if (pCreature->GetVendorItemCurrentCount(crItem) < totalCount) { - SendBuyError( BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); + SendBuyError(BUY_ERR_ITEM_ALREADY_SOLD, pCreature, item, 0); return false; } } if (uint32(GetReputationRank(pProto->RequiredReputationFaction)) < pProto->RequiredReputationRank) { - SendBuyError( BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); + SendBuyError(BUY_ERR_REPUTATION_REQUIRE, pCreature, item, 0); return false; } @@ -18923,9 +18941,9 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin } // item base price - for (uint8 i = 0; i < 5; ++i) + for (uint8 i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i) { - if(iece->reqitem[i] && !HasItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count))) + if (iece->reqitem[i] && !HasItemCount(iece->reqitem[i], iece->reqitemcount[i] * count)) { SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); return false; @@ -18933,15 +18951,15 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin } // check for personal arena rating requirement - if( GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating ) + if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating) { // probably not the proper equip err - SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK,NULL,NULL); + SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL); return false; } } - uint32 price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? pProto->BuyPrice * count : 0; + uint32 price = (crItem->ExtendedCost == 0 || pProto->Flags2 & ITEM_FLAG2_EXT_COST_REQUIRES_GOLD) ? pProto->BuyPrice * count : 0; // reputation discount if (price) @@ -18949,102 +18967,75 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin if (GetMoney() < price) { - SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); + SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, item, 0); return false; } + Item* pItem = NULL; + if ((bag == NULL_BAG && slot == NULL_SLOT) || IsInventoryPos(bag, slot)) { ItemPosCountVec dest; - uint8 msg = CanStoreNewItem( bag, slot, dest, item, pProto->BuyCount * count ); + uint8 msg = CanStoreNewItem(bag, slot, dest, item, totalCount); if (msg != EQUIP_ERR_OK) { - SendEquipError( msg, NULL, NULL, item ); + SendEquipError(msg, NULL, NULL, item); return false; } - ModifyMoney( -(int32)price ); - if (uint32 extendedCostId = crItem->ExtendedCost) - { - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); - if (iece->reqhonorpoints) - ModifyHonorPoints( - int32(iece->reqhonorpoints * count)); - if (iece->reqarenapoints) - ModifyArenaPoints( - int32(iece->reqarenapoints * count)); - for (uint8 i = 0; i < 5; ++i) - { - if (iece->reqitem[i]) - DestroyItemCount(iece->reqitem[i], (iece->reqitemcount[i] * count), true); - } - } + ModifyMoney(-int32(price)); - if (Item *it = StoreNewItem( dest, item, true )) - { - uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); + if (crItem->ExtendedCost) + TakeExtendedCost(crItem->ExtendedCost, count); - WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); - data << pCreature->GetObjectGuid(); - data << uint32(vendorslot+1); // numbered from 1 at client - data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); - data << uint32(count); - GetSession()->SendPacket(&data); - - SendNewItem(it, pProto->BuyCount*count, true, false, false); - } + pItem = StoreNewItem(dest, item, true); } else if (IsEquipmentPos(bag, slot)) { - if (pProto->BuyCount * count != 1) + if (totalCount != 1) { - SendEquipError( EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL ); + SendEquipError(EQUIP_ERR_ITEM_CANT_BE_EQUIPPED, NULL, NULL); return false; } uint16 dest; - uint8 msg = CanEquipNewItem( slot, dest, item, false ); + uint8 msg = CanEquipNewItem(slot, dest, item, false); if (msg != EQUIP_ERR_OK) { - SendEquipError( msg, NULL, NULL, item ); + SendEquipError(msg, NULL, NULL, item); return false; } - ModifyMoney( -(int32)price ); - if (uint32 extendedCostId = crItem->ExtendedCost) - { - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); - if (iece->reqhonorpoints) - ModifyHonorPoints( - int32(iece->reqhonorpoints)); - if (iece->reqarenapoints) - ModifyArenaPoints( - int32(iece->reqarenapoints)); - for (uint8 i = 0; i < 5; ++i) - { - if(iece->reqitem[i]) - DestroyItemCount(iece->reqitem[i], iece->reqitemcount[i], true); - } - } + ModifyMoney(-int32(price)); - if (Item *it = EquipNewItem( dest, item, true )) - { - uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem,pProto->BuyCount * count); + if (crItem->ExtendedCost) + TakeExtendedCost(crItem->ExtendedCost, count); - WorldPacket data(SMSG_BUY_ITEM, (8+4+4+4)); - data << pCreature->GetObjectGuid(); - data << uint32(vendorslot + 1); // numbered from 1 at client - data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); - data << uint32(count); - GetSession()->SendPacket(&data); - - SendNewItem(it, pProto->BuyCount*count, true, false, false); + pItem = EquipNewItem(dest, item, true); + if (pItem) AutoUnequipOffhandIfNeed(); - } } else { - SendEquipError( EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL ); + SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); return false; } + if (!pItem) + return false; + + uint32 new_count = pCreature->UpdateVendorItemCurrentCount(crItem, totalCount); + + WorldPacket data(SMSG_BUY_ITEM, 8+4+4+4); + data << pCreature->GetObjectGuid(); + data << uint32(vendorslot + 1); // numbered from 1 at client + data << uint32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); + data << uint32(count); + GetSession()->SendPacket(&data); + + SendNewItem(pItem, totalCount, true, false, false); + return crItem->maxcount != 0; } diff --git a/src/game/Player.h b/src/game/Player.h index 7318639eb..0ca7ba2e3 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1330,6 +1330,9 @@ class MANGOS_DLL_SPEC Player : public Unit void AddItemToBuyBackSlot( Item *pItem ); Item* GetItemFromBuyBackSlot( uint32 slot ); void RemoveItemFromBuyBackSlot( uint32 slot, bool del ); + + void TakeExtendedCost(uint32 extendedCostId, uint32 count); + uint32 GetMaxKeyringSize() const { return KEYRING_SLOT_END-KEYRING_SLOT_START; } void SendEquipError( uint8 msg, Item* pItem, Item *pItem2 = NULL, uint32 itemid = 0 ) const; void SendBuyError( uint8 msg, Creature* pCreature, uint32 item, uint32 param ); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6dde8ace6..40453ac3b 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11208" + #define REVISION_NR "11209" #endif // __REVISION_NR_H__