diff --git a/src/game/DB2Structure.h b/src/game/DB2Structure.h index 721141de4..2a43ba4e4 100644 --- a/src/game/DB2Structure.h +++ b/src/game/DB2Structure.h @@ -50,19 +50,41 @@ struct ItemCurrencyCostEntry #define MAX_EXTENDED_COST_ITEMS 5 #define MAX_EXTENDED_COST_CURRENCIES 5 +enum ItemExtendedCostFlags +{ + ITEM_EXTENDED_COST_FLAG_UNK = 0x01, // guild related + ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_0 = 0x02, // currency requirements under these indexes require season count + ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_1 = 0x04, + ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_2 = 0x08, + ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_3 = 0x10, + ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_4 = 0x20, +}; + struct ItemExtendedCostEntry { uint32 Id; // 0 - uint32 reqhonorpoints; // 1 m_honorPoints - uint32 reqarenapoints; // 2 m_arenaPoints + // // 1 unk, old reqhonorpoints + // // 2 unk, old reqarenapoints uint32 reqarenaslot; // 3 m_arenaBracket uint32 reqitem[MAX_EXTENDED_COST_ITEMS]; // 5-8 m_itemID uint32 reqitemcount[MAX_EXTENDED_COST_ITEMS]; // 9-13 m_itemCount uint32 reqpersonalarenarating; // 14 m_requiredArenaRating //uint32 // 15 m_itemPurchaseGroup - uint32 reqcur[MAX_EXTENDED_COST_CURRENCIES]; // 16-20 - uint32 reqcurrcount[MAX_EXTENDED_COST_CURRENCIES]; // 21-25 - //uint32 something[5]; // 26-30 + uint32 reqcur[MAX_EXTENDED_COST_CURRENCIES]; // 16-20 + uint32 reqcurrcount[MAX_EXTENDED_COST_CURRENCIES]; // 21-25 + // 26 reputation-related + // 27 reputation-related + uint32 flags; // 28 + // // 29 + // // 30 + + bool IsSeasonCurrencyRequirement(uint32 i) const + { + MANGOS_ASSERT(i < MAX_EXTENDED_COST_CURRENCIES); + + // start from ITEM_EXTENDED_COST_FLAG_SEASON_IN_INDEX_0 + return flags & 1 << (i + 1); + } }; #endif diff --git a/src/game/DB2fmt.h b/src/game/DB2fmt.h index 33300528f..4f0e2c220 100644 --- a/src/game/DB2fmt.h +++ b/src/game/DB2fmt.h @@ -21,6 +21,6 @@ const char Itemfmt[]="niiiiiii"; const char ItemCurrencyCostfmt[]="di"; -const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiixiiiiiiiiiixxxxx"; +const char ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiixxixx"; #endif diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 88e188930..0eaee8cb8 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18966,16 +18966,27 @@ 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); } + + for (int i = 0; i < MAX_EXTENDED_COST_CURRENCIES; ++i) + { + if (extendedCost->reqcur[i] == CURRENCY_NONE) + continue; + + if (extendedCost->IsSeasonCurrencyRequirement(i)) + continue; + + CurrencyTypesEntry const * entry = sCurrencyTypesStore.LookupEntry(extendedCost->reqcur[i]); + if (!entry) + continue; + + int32 cost = int32(extendedCost->reqcurrcount[i] * count); + ModifyCurrencyCount(entry->ID, -cost); + } } // Return true is the bought item has a max count to force refresh of window by caller @@ -19063,27 +19074,13 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin if (uint32 extendedCostId = crItem->ExtendedCost) { - ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); + ItemExtendedCostEntry const* iece = sItemExtendedCostStore.LookupEntry(extendedCostId); if (!iece) { sLog.outError("Item %u have wrong ExtendedCost field value %u", pProto->ItemId, extendedCostId); return false; } - // honor points price - //if (GetHonorPoints() < (iece->reqhonorpoints * count)) - //{ - // SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); - // return false; - //} - - // arena points price - //if (GetArenaPoints() < (iece->reqarenapoints * count)) - //{ - // SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); - // return false; - //} - // item base price for (uint8 i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i) { @@ -19094,6 +19091,29 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, uin } } + // currency price + for (uint8 i = 0; i < MAX_EXTENDED_COST_CURRENCIES; ++i) + { + if (iece->reqcur[i] == CURRENCY_NONE) + continue; + + CurrencyTypesEntry const * costCurrency = sCurrencyTypesStore.LookupEntry(iece->reqcur[i]); + if (!costCurrency) + { + sLog.outError("Item %u has ExtendedCost %u with unexistent currency id %u", pProto->ItemId, extendedCostId, iece->reqcur[i]); + continue; + } + + int32 cost = int32(iece->reqcurrcount[i] * count); + + bool hasCount = iece->IsSeasonCurrencyRequirement(i) ? HasCurrencySeasonCount(iece->reqcur[i], cost) : HasCurrencyCount(iece->reqcur[i], cost); + if (!hasCount) + { + SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL); + return false; + } + } + // check for personal arena rating requirement if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating) { @@ -19239,20 +19259,6 @@ bool Player::BuyCurrencyFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, return false; } - // honor points price - //if (GetHonorPoints() < (iece->reqhonorpoints * count)) - //{ - // SendEquipError(EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS, NULL, NULL); - // return false; - //} - - // arena points price - //if (GetArenaPoints() < (iece->reqarenapoints * count)) - //{ - // SendEquipError(EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS, NULL, NULL); - // return false; - //} - // item base price for (uint8 i = 0; i < MAX_EXTENDED_COST_ITEMS; ++i) { @@ -19263,6 +19269,28 @@ bool Player::BuyCurrencyFromVendorSlot(ObjectGuid vendorGuid, uint32 vendorslot, } } + // currency price + for (uint8 i = 0; i < MAX_EXTENDED_COST_CURRENCIES; ++i) + { + if (iece->reqcur[i] == CURRENCY_NONE) + continue; + + CurrencyTypesEntry const * costCurrency = sCurrencyTypesStore.LookupEntry(iece->reqcur[i]); + if (!costCurrency) + { + sLog.outError("Currency %u has ExtendedCost %u with unexistent currency id %u", currencyId, extendedCostId, iece->reqcur[i]); + continue; + } + + int32 cost = int32(iece->reqcurrcount[i] * count); + bool hasCount = iece->IsSeasonCurrencyRequirement(i) ? HasCurrencySeasonCount(iece->reqcur[i], cost) : HasCurrencyCount(iece->reqcur[i], cost); + if (!hasCount) + { + SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL); + return false; + } + } + // check for personal arena rating requirement if (GetMaxPersonalArenaRatingRequirement(iece->reqarenaslot) < iece->reqpersonalarenarating) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 07cd1e39b..50dd51d8c 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 "12142" + #define REVISION_NR "12143" #endif // __REVISION_NR_H__