mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 01:15:35 +01:00
Core/Creatures: Implemented new extended cost requirements and fixed some items requiring too much honor/conquest points
This commit is contained in:
@@ -135,7 +135,11 @@ struct ItemExtendedCostEntry
|
||||
//uint32 ItemPurchaseGroup; // 15
|
||||
uint32 RequiredCurrency[MAX_ITEM_EXT_COST_CURRENCIES];// 16-20 required curency id
|
||||
uint32 RequiredCurrencyCount[MAX_ITEM_EXT_COST_CURRENCIES];// 21-25 required curency count
|
||||
//uint32 Unknown[5]; // 26-30
|
||||
uint32 RequiredFactionId;
|
||||
uint32 RequiredFactionStanding;
|
||||
uint32 RequirementFlags;
|
||||
uint32 RequiredGuildLevel;
|
||||
uint32 RequiredAchievement;
|
||||
};
|
||||
|
||||
#define KEYCHAIN_SIZE 32
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
char const Itemfmt[]="niiiiiii";
|
||||
char const ItemCurrencyCostfmt[]="xn";
|
||||
char const ItemSparsefmt[]="niiiffiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiisssssiiiiiiiiiiiiiiiiiiiiiifiiifii";
|
||||
char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiixxxxx";
|
||||
char const ItemExtendedCostEntryfmt[]="nxxiiiiiiiiiiiixiiiiiiiiiiiiiii";
|
||||
char const KeyChainfmt[]="nbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
|
||||
|
||||
#endif
|
||||
|
||||
@@ -405,6 +405,16 @@ enum ItemEnchantmentType
|
||||
ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET = 8
|
||||
};
|
||||
|
||||
enum ItemExtendedCostFlags
|
||||
{
|
||||
ITEM_EXT_COST_FLAG_REQUIRE_GUILD = 0x01,
|
||||
ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 = 0x02,
|
||||
ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_2 = 0x04,
|
||||
ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_3 = 0x08,
|
||||
ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_4 = 0x10,
|
||||
ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_5 = 0x20,
|
||||
};
|
||||
|
||||
enum ItemLimitCategoryMode
|
||||
{
|
||||
ITEM_LIMIT_CATEGORY_MODE_HAVE = 0, // limit applied to amount items in inventory/bank
|
||||
|
||||
@@ -348,7 +348,7 @@ struct VendorItemData
|
||||
return m_items[slot];
|
||||
}
|
||||
bool Empty() const { return m_items.empty(); }
|
||||
uint8 GetItemCount() const { return m_items.size(); }
|
||||
uint32 GetItemCount() const { return m_items.size(); }
|
||||
void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type)
|
||||
{
|
||||
m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost, type));
|
||||
@@ -412,7 +412,7 @@ typedef std::map<uint32, time_t> CreatureSpellCooldowns;
|
||||
// max different by z coordinate for creature aggro reaction
|
||||
#define CREATURE_Z_ATTACK_RANGE 3
|
||||
|
||||
#define MAX_VENDOR_ITEMS 300 // Limitation in 4.x.x item count in SMSG_LIST_INVENTORY
|
||||
#define MAX_VENDOR_ITEMS 150 // Limitation in 4.x.x item count in SMSG_LIST_INVENTORY
|
||||
|
||||
enum CreatureCellMoveState
|
||||
{
|
||||
|
||||
@@ -21656,6 +21656,9 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c
|
||||
|
||||
for (int i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
|
||||
{
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
continue;
|
||||
|
||||
if (iece->RequiredCurrency[i])
|
||||
ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i] * stacks), true, true);
|
||||
}
|
||||
@@ -21774,7 +21777,13 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * stacks)))
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
{
|
||||
// Not implemented
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
else if (!HasCurrency(iece->RequiredCurrency[i], (iece->RequiredCurrencyCount[i] * stacks)))
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
@@ -21788,6 +21797,30 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin
|
||||
SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredFactionId && GetReputationRank(iece->RequiredFactionId) < iece->RequiredFactionStanding)
|
||||
{
|
||||
SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, currency, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequirementFlags & ITEM_EXT_COST_FLAG_REQUIRE_GUILD && !GetGuildId())
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredGuildLevel && iece->RequiredGuildLevel < GetGuildLevel())
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredAchievement && !HasAchieved(iece->RequiredAchievement))
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // currencies have no price defined, can only be bought with ExtendedCost
|
||||
{
|
||||
@@ -21811,6 +21844,9 @@ bool Player::BuyCurrencyFromVendorSlot(uint64 vendorGuid, uint32 vendorSlot, uin
|
||||
if (!iece->RequiredCurrency[i])
|
||||
continue;
|
||||
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
continue;
|
||||
|
||||
ModifyCurrency(iece->RequiredCurrency[i], -int32(iece->RequiredCurrencyCount[i]) * stacks, false, true);
|
||||
}
|
||||
}
|
||||
@@ -21921,7 +21957,12 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!HasCurrency(iece->RequiredCurrency[i], iece->RequiredCurrencyCount[i] * stacks))
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
else if (!HasCurrency(iece->RequiredCurrency[i], iece->RequiredCurrencyCount[i] * stacks))
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL);
|
||||
return false;
|
||||
@@ -21935,6 +21976,30 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32
|
||||
SendEquipError(EQUIP_ERR_CANT_EQUIP_RANK, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredFactionId && GetReputationRank(iece->RequiredFactionId) < iece->RequiredFactionStanding)
|
||||
{
|
||||
SendBuyError(BUY_ERR_REPUTATION_REQUIRE, creature, item, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequirementFlags & ITEM_EXT_COST_FLAG_REQUIRE_GUILD && !GetGuildId())
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredGuildLevel && iece->RequiredGuildLevel < GetGuildLevel())
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iece->RequiredAchievement && !HasAchieved(iece->RequiredAchievement))
|
||||
{
|
||||
SendEquipError(EQUIP_ERR_VENDOR_MISSING_TURNINS, NULL, NULL); // Find correct error
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 price = 0;
|
||||
@@ -26610,6 +26675,13 @@ void Player::SendRefundInfo(Item* item)
|
||||
data.WriteByteSeq(guid[2]);
|
||||
for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data
|
||||
{
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
{
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
|
||||
uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
|
||||
|
||||
@@ -26667,6 +26739,13 @@ void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece,
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
|
||||
{
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
{
|
||||
data << uint32(0);
|
||||
data << uint32(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
|
||||
uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
|
||||
|
||||
@@ -26780,6 +26859,9 @@ void Player::RefundItem(Item* item)
|
||||
// Grant back currencies
|
||||
for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
|
||||
{
|
||||
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
|
||||
continue;
|
||||
|
||||
uint32 count = iece->RequiredCurrencyCount[i];
|
||||
uint32 currencyid = iece->RequiredCurrency[i];
|
||||
if (count && currencyid)
|
||||
|
||||
@@ -571,7 +571,7 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
vendor->StopMoving();
|
||||
|
||||
VendorItemData const* vendorItems = vendor->GetVendorItems();
|
||||
uint8 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
|
||||
uint32 rawItemCount = vendorItems ? vendorItems->GetItemCount() : 0;
|
||||
|
||||
//if (rawItemCount > 300),
|
||||
// rawItemCount = 300; // client cap but uint8 max value is 255
|
||||
@@ -582,10 +582,11 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
|
||||
const float discountMod = _player->GetReputationPriceDiscount(vendor);
|
||||
uint8 count = 0;
|
||||
for (uint8 slot = 0; slot < rawItemCount; ++slot)
|
||||
for (uint32 slot = 0; slot < rawItemCount; ++slot)
|
||||
{
|
||||
VendorItem const* vendorItem = vendorItems->GetItem(slot);
|
||||
if (!vendorItem) continue;
|
||||
if (!vendorItem)
|
||||
continue;
|
||||
|
||||
if (vendorItem->Type == ITEM_VENDOR_TYPE_ITEM)
|
||||
{
|
||||
@@ -622,18 +623,18 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
if (int32 priceMod = _player->GetTotalAuraModifier(SPELL_AURA_MOD_VENDOR_ITEMS_PRICES))
|
||||
price -= CalculatePct(price, priceMod);
|
||||
|
||||
++count;
|
||||
itemsData << uint32(slot + 1); // client expects counting to start at 1
|
||||
itemsData << uint32(itemTemplate->MaxDurability);
|
||||
|
||||
if (vendorItem->ExtendedCost != 0)
|
||||
if (vendorItem->ExtendedCost)
|
||||
{
|
||||
enablers.push_back(0);
|
||||
itemsData << uint32(vendorItem->ExtendedCost);
|
||||
}
|
||||
else
|
||||
enablers.push_back(1);
|
||||
enablers.push_back(1); // unk bit
|
||||
|
||||
enablers.push_back(1); // item is unlocked
|
||||
|
||||
itemsData << uint32(vendorItem->item);
|
||||
itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
|
||||
@@ -642,6 +643,9 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
// if (!unk "enabler") data << uint32(something);
|
||||
itemsData << int32(leftInStock);
|
||||
itemsData << uint32(itemTemplate->BuyCount);
|
||||
|
||||
if (++count >= MAX_VENDOR_ITEMS)
|
||||
break;
|
||||
}
|
||||
else if (vendorItem->Type == ITEM_VENDOR_TYPE_CURRENCY)
|
||||
{
|
||||
@@ -649,22 +653,16 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
if (!currencyTemplate)
|
||||
continue;
|
||||
|
||||
if (vendorItem->ExtendedCost == 0)
|
||||
if (!vendorItem->ExtendedCost)
|
||||
continue; // there's no price defined for currencies, only extendedcost is used
|
||||
|
||||
++count;
|
||||
itemsData << uint32(slot + 1); // client expects counting to start at 1
|
||||
itemsData << uint32(0); // max durability
|
||||
|
||||
if (vendorItem->ExtendedCost != 0)
|
||||
{
|
||||
enablers.push_back(0);
|
||||
itemsData << uint32(vendorItem->ExtendedCost);
|
||||
}
|
||||
else
|
||||
enablers.push_back(1);
|
||||
enablers.push_back(0);
|
||||
itemsData << uint32(vendorItem->ExtendedCost);
|
||||
|
||||
enablers.push_back(1); // unk bit
|
||||
enablers.push_back(1); // item is unlocked
|
||||
|
||||
itemsData << uint32(vendorItem->item);
|
||||
itemsData << uint32(vendorItem->Type); // 1 is items, 2 is currency
|
||||
@@ -673,6 +671,9 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
// if (!unk "enabler") data << uint32(something);
|
||||
itemsData << int32(-1);
|
||||
itemsData << uint32(vendorItem->maxcount);
|
||||
|
||||
if (++count >= MAX_VENDOR_ITEMS)
|
||||
break;
|
||||
}
|
||||
// else error
|
||||
}
|
||||
@@ -706,7 +707,13 @@ void WorldSession::SendListInventory(uint64 vendorGuid)
|
||||
data.WriteByteSeq(guid[0]);
|
||||
data.WriteByteSeq(guid[6]);
|
||||
|
||||
data << uint8(count == 0); // unk byte, item count 0: 1, item count != 0: 0 or some "random" value below 300
|
||||
// It doesn't matter what value is used here (PROBABLY its full vendor size)
|
||||
// What matters is that if count of items we can see is 0 and this field is 1
|
||||
// then client will open the vendor list, otherwise it won't
|
||||
if (rawItemCount)
|
||||
data << uint8(rawItemCount);
|
||||
else
|
||||
data << uint8(vendor->IsArmorer());
|
||||
|
||||
data.WriteByteSeq(guid[2]);
|
||||
data.WriteByteSeq(guid[3]);
|
||||
|
||||
Reference in New Issue
Block a user