fix(Core/Trade): correct packets, exchange checks, distance logic (#24710)
Co-authored-by: Wyrserth <wyrserth@protonmail.com> Co-authored-by: Shauren <shauren.trinity@gmail.com> Co-authored-by: Alan Deutscher <adeutscher@gmail.com> Co-authored-by: Dehravor <dehravor@gmail.com> Co-authored-by: robinsch <robinsch@users.noreply.github.com> Co-authored-by: killerwife <killerwife@gmail.com>
This commit is contained in:
@@ -1057,6 +1057,18 @@ struct EntryPointData
|
||||
[[nodiscard]] bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; }
|
||||
};
|
||||
|
||||
struct TradeStatusInfo
|
||||
{
|
||||
TradeStatusInfo() = default;
|
||||
|
||||
TradeStatus Status{TRADE_STATUS_BUSY};
|
||||
ObjectGuid TraderGuid{};
|
||||
InventoryResult Result{EQUIP_ERR_OK};
|
||||
bool IsTargetResult{false};
|
||||
uint32 ItemLimitedByLimitCategory{0};
|
||||
uint8 Slot{0};
|
||||
};
|
||||
|
||||
struct PendingSpellCastRequest
|
||||
{
|
||||
uint32 spellId;
|
||||
@@ -1277,12 +1289,17 @@ public:
|
||||
bool CanNoReagentCast(SpellInfo const* spellInfo) const;
|
||||
[[nodiscard]] bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const;
|
||||
[[nodiscard]] bool HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const;
|
||||
InventoryResult CanTakeMoreSimilarItems(Item* pItem) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem); }
|
||||
[[nodiscard]] InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return CanTakeMoreSimilarItems(entry, count, nullptr); }
|
||||
|
||||
InventoryResult CanTakeMoreSimilarItems(Item* item, uint32* itemLimitedByLimitCategory = nullptr) const
|
||||
{
|
||||
return CanTakeMoreSimilarItems(item->GetEntry(), item->GetCount(), item, nullptr, itemLimitedByLimitCategory);
|
||||
}
|
||||
InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitedByLimitCategory = nullptr) const { return CanTakeMoreSimilarItems(entry, count, nullptr, nullptr, itemLimitedByLimitCategory); }
|
||||
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = nullptr) const
|
||||
{
|
||||
return CanStoreItem(bag, slot, dest, item, count, nullptr, false, no_space_count);
|
||||
}
|
||||
|
||||
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const
|
||||
{
|
||||
if (!pItem)
|
||||
@@ -1290,7 +1307,7 @@ public:
|
||||
uint32 count = pItem->GetCount();
|
||||
return CanStoreItem(bag, slot, dest, pItem->GetEntry(), count, pItem, swap, nullptr);
|
||||
}
|
||||
InventoryResult CanStoreItems(Item** pItem, int32 count) const;
|
||||
InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitedByLimitCategory) const;
|
||||
InventoryResult CanEquipNewItem(uint8 slot, uint16& dest, uint32 item, bool swap) const;
|
||||
InventoryResult CanEquipItem(uint8 slot, uint16& dest, Item* pItem, bool swap, bool not_loading = true) const;
|
||||
|
||||
@@ -1318,7 +1335,7 @@ public:
|
||||
void UpdateLootAchievements(LootItem* item, Loot* loot);
|
||||
void UpdateTitansGrip();
|
||||
|
||||
InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = nullptr) const;
|
||||
InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* item, uint32* no_space_count = nullptr, uint32* itemLimitCategory = nullptr) const;
|
||||
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = nullptr, bool swap = false, uint32* no_space_count = nullptr) const;
|
||||
|
||||
void AddRefundReference(ObjectGuid itemGUID);
|
||||
|
||||
@@ -799,7 +799,7 @@ bool Player::HasItemOrGemWithLimitCategoryEquipped(uint32 limitCategory, uint32
|
||||
return false;
|
||||
}
|
||||
|
||||
InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count) const
|
||||
InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* item, uint32* no_space_count /*= nullptr*/, uint32* itemLimitedByLimitCategory /*= nullptr*/) const
|
||||
{
|
||||
ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry);
|
||||
if (!pProto)
|
||||
@@ -809,13 +809,16 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
|
||||
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
|
||||
}
|
||||
|
||||
if (item && item->m_lootGenerated)
|
||||
return EQUIP_ERR_ALREADY_LOOTED;
|
||||
|
||||
// no maximum
|
||||
if ((pProto->MaxCount <= 0 && pProto->ItemLimitCategory == 0) || pProto->MaxCount == 2147483647)
|
||||
return EQUIP_ERR_OK;
|
||||
|
||||
if (pProto->MaxCount > 0)
|
||||
{
|
||||
uint32 curcount = GetItemCount(pProto->ItemId, true, pItem);
|
||||
uint32 curcount = GetItemCount(pProto->ItemId, true, item);
|
||||
if (curcount + count > uint32(pProto->MaxCount))
|
||||
{
|
||||
if (no_space_count)
|
||||
@@ -837,11 +840,13 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item
|
||||
|
||||
if (limitEntry->mode == ITEM_LIMIT_CATEGORY_MODE_HAVE)
|
||||
{
|
||||
uint32 curcount = GetItemCountWithLimitCategory(pProto->ItemLimitCategory, pItem);
|
||||
uint32 curcount = GetItemCountWithLimitCategory(pProto->ItemLimitCategory, item);
|
||||
if (curcount + count > uint32(limitEntry->maxCount))
|
||||
{
|
||||
if (no_space_count)
|
||||
*no_space_count = count + curcount - limitEntry->maxCount;
|
||||
if (itemLimitedByLimitCategory)
|
||||
*itemLimitedByLimitCategory = pProto->ItemId;
|
||||
return EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED;
|
||||
}
|
||||
}
|
||||
@@ -1119,7 +1124,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des
|
||||
if (pItem->IsBag() && pItem->IsNotEmptyBag())
|
||||
return EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS;
|
||||
|
||||
// Xinef: Removed next loot generated check
|
||||
// swapping/merging with currently looted item
|
||||
if (pItem->GetGUID() == GetLootGUID())
|
||||
{
|
||||
if (no_space_count)
|
||||
@@ -1538,79 +1543,102 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
InventoryResult Player::CanStoreItems(Item** items, int count, uint32* itemLimitedByLimitCategory) const
|
||||
{
|
||||
Item* pItem2;
|
||||
Item* item2;
|
||||
|
||||
// fill space table
|
||||
int inv_slot_items[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START];
|
||||
int inv_bags[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];
|
||||
int inv_keys[KEYRING_SLOT_END - KEYRING_SLOT_START];
|
||||
int inv_tokens[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START];
|
||||
// fill space tables, creating a mock-up of the player's inventory
|
||||
|
||||
memset(inv_slot_items, 0, sizeof(int) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
|
||||
memset(inv_bags, 0, sizeof(int) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE);
|
||||
memset(inv_keys, 0, sizeof(int) * (KEYRING_SLOT_END - KEYRING_SLOT_START));
|
||||
memset(inv_tokens, 0, sizeof(int) * (CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START));
|
||||
// counts
|
||||
uint32 inventoryCounts[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {};
|
||||
uint32 bagCounts[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {};
|
||||
uint32 keyringCounts[KEYRING_SLOT_END - KEYRING_SLOT_START] = {};
|
||||
uint32 currencyCounts[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START] = {};
|
||||
|
||||
// Item pointers
|
||||
Item* inventoryPointers[INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START] = {};
|
||||
Item* bagPointers[INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE] = {};
|
||||
Item* keyringPointers[KEYRING_SLOT_END - KEYRING_SLOT_START] = {};
|
||||
Item* currencyPointers[CURRENCYTOKEN_SLOT_END - CURRENCYTOKEN_SLOT_START] = {};
|
||||
|
||||
// filling inventory
|
||||
for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (pItem2 && !pItem2->IsInTrade())
|
||||
inv_slot_items[i - INVENTORY_SLOT_ITEM_START] = pItem2->GetCount();
|
||||
// build items in stock backpack
|
||||
item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (item2 && !item2->IsInTrade())
|
||||
{
|
||||
inventoryCounts[i - INVENTORY_SLOT_ITEM_START] = item2->GetCount();
|
||||
inventoryPointers[i - INVENTORY_SLOT_ITEM_START] = item2;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (pItem2 && !pItem2->IsInTrade())
|
||||
inv_keys[i - KEYRING_SLOT_START] = pItem2->GetCount();
|
||||
// build items in key ring 'bag'
|
||||
item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (item2 && !item2->IsInTrade())
|
||||
{
|
||||
keyringCounts[i - KEYRING_SLOT_START] = item2->GetCount();
|
||||
keyringPointers[i - KEYRING_SLOT_START] = item2;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (pItem2 && !pItem2->IsInTrade())
|
||||
inv_tokens[i - CURRENCYTOKEN_SLOT_START] = pItem2->GetCount();
|
||||
// build items in currency 'bag'
|
||||
item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i);
|
||||
if (item2 && !item2->IsInTrade())
|
||||
{
|
||||
currencyCounts[i - CURRENCYTOKEN_SLOT_START] = item2->GetCount();
|
||||
currencyPointers[i - CURRENCYTOKEN_SLOT_START] = item2;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8 i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)
|
||||
if (Bag* pBag = GetBagByPos(i))
|
||||
for (uint32 j = 0; j < pBag->GetBagSize(); j++)
|
||||
{
|
||||
pItem2 = GetItemByPos(i, j);
|
||||
if (pItem2 && !pItem2->IsInTrade())
|
||||
inv_bags[i - INVENTORY_SLOT_BAG_START][j] = pItem2->GetCount();
|
||||
// build item counts in equippable bags
|
||||
item2 = GetItemByPos(i, j);
|
||||
if (item2 && !item2->IsInTrade())
|
||||
{
|
||||
bagCounts[i - INVENTORY_SLOT_BAG_START][j] = item2->GetCount();
|
||||
bagPointers[i - INVENTORY_SLOT_BAG_START][j] = item2;
|
||||
}
|
||||
}
|
||||
|
||||
// check free space for all items
|
||||
// check free space for all items that we wish to add
|
||||
for (int k = 0; k < count; ++k)
|
||||
{
|
||||
Item* pItem = pItems[k];
|
||||
// Incoming item
|
||||
Item* item = items[k];
|
||||
|
||||
// no item
|
||||
if (!pItem)
|
||||
if (!item)
|
||||
continue;
|
||||
|
||||
LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems {}. item = {}, count = {}", k + 1, pItem->GetEntry(), pItem->GetCount());
|
||||
ItemTemplate const* pProto = pItem->GetTemplate();
|
||||
uint32 remaining_count = item->GetCount();
|
||||
|
||||
LOG_DEBUG("entities.player.items", "STORAGE: CanStoreItems {}. item = {}, count = {}", k + 1, item->GetEntry(), item->GetCount());
|
||||
ItemTemplate const* pProto = item->GetTemplate();
|
||||
|
||||
// strange item
|
||||
if (!pProto)
|
||||
return EQUIP_ERR_ITEM_NOT_FOUND;
|
||||
|
||||
// Xinef: Removed next loot generated check
|
||||
if (pItem->GetGUID() == GetLootGUID())
|
||||
/// swapping/merging with currently looted item
|
||||
if (item->GetGUID() == GetLootGUID())
|
||||
return EQUIP_ERR_ALREADY_LOOTED;
|
||||
|
||||
// item it 'bind'
|
||||
if (pItem->IsBindedNotWith(this))
|
||||
if (item->IsBindedNotWith(this))
|
||||
return EQUIP_ERR_DONT_OWN_THAT_ITEM;
|
||||
|
||||
ItemTemplate const* pBagProto;
|
||||
|
||||
// item is 'one item only'
|
||||
InventoryResult res = CanTakeMoreSimilarItems(pItem);
|
||||
InventoryResult res = CanTakeMoreSimilarItems(item, itemLimitedByLimitCategory);
|
||||
if (res != EQUIP_ERR_OK)
|
||||
return res;
|
||||
|
||||
@@ -1621,40 +1649,58 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
|
||||
for (uint8 t = KEYRING_SLOT_START; t < KEYRING_SLOT_END; ++t)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
|
||||
if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_keys[t - KEYRING_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
|
||||
item2 = keyringPointers[t - KEYRING_SLOT_START];
|
||||
if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize())
|
||||
{
|
||||
inv_keys[t - KEYRING_SLOT_START] += pItem->GetCount();
|
||||
b_found = true;
|
||||
break;
|
||||
keyringCounts[t - KEYRING_SLOT_START] += remaining_count;
|
||||
remaining_count = keyringCounts[t - KEYRING_SLOT_START] < pProto->GetMaxStackSize() ? 0 : keyringCounts[t - KEYRING_SLOT_START] - pProto->GetMaxStackSize();
|
||||
|
||||
b_found = remaining_count == 0;
|
||||
|
||||
// if no pieces of the stack remain, then stop checking keyring
|
||||
if (b_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
|
||||
for (int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
|
||||
if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_tokens[t - CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
|
||||
item2 = currencyPointers[t - CURRENCYTOKEN_SLOT_START];
|
||||
if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && currencyCounts[t - CURRENCYTOKEN_SLOT_START] < pProto->GetMaxStackSize())
|
||||
{
|
||||
inv_tokens[t - CURRENCYTOKEN_SLOT_START] += pItem->GetCount();
|
||||
b_found = true;
|
||||
break;
|
||||
currencyCounts[t - CURRENCYTOKEN_SLOT_START] += remaining_count;
|
||||
remaining_count =
|
||||
currencyCounts[t - CURRENCYTOKEN_SLOT_START] < pProto->GetMaxStackSize() ? 0 : currencyCounts[t - CURRENCYTOKEN_SLOT_START] - pProto->GetMaxStackSize();
|
||||
|
||||
b_found = remaining_count == 0;
|
||||
// if no pieces of the stack remain, then stop checking currency 'bag'
|
||||
if (b_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
|
||||
for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t)
|
||||
{
|
||||
pItem2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t);
|
||||
if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_slot_items[t - INVENTORY_SLOT_ITEM_START] + pItem->GetCount() <= pProto->GetMaxStackSize())
|
||||
item2 = inventoryPointers[t - INVENTORY_SLOT_ITEM_START];
|
||||
if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inventoryCounts[t - INVENTORY_SLOT_ITEM_START] < pProto->GetMaxStackSize())
|
||||
{
|
||||
inv_slot_items[t - INVENTORY_SLOT_ITEM_START] += pItem->GetCount();
|
||||
b_found = true;
|
||||
break;
|
||||
inventoryCounts[t - INVENTORY_SLOT_ITEM_START] += remaining_count;
|
||||
remaining_count =
|
||||
inventoryCounts[t - INVENTORY_SLOT_ITEM_START] < pProto->GetMaxStackSize() ? 0 : inventoryCounts[t - INVENTORY_SLOT_ITEM_START] - pProto->GetMaxStackSize();
|
||||
|
||||
b_found = remaining_count == 0;
|
||||
// if no pieces of the stack remain, then stop checking stock bag
|
||||
if (b_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
|
||||
@@ -1662,21 +1708,29 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
{
|
||||
if (Bag* bag = GetBagByPos(t))
|
||||
{
|
||||
if (ItemCanGoIntoBag(pItem->GetTemplate(), bag->GetTemplate()))
|
||||
if (!ItemCanGoIntoBag(item->GetTemplate(), bag->GetTemplate()))
|
||||
continue;
|
||||
|
||||
for (uint32 j = 0; j < bag->GetBagSize(); j++)
|
||||
{
|
||||
for (uint32 j = 0; j < bag->GetBagSize(); j++)
|
||||
item2 = bagPointers[t - INVENTORY_SLOT_BAG_START][j];
|
||||
if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && bagCounts[t - INVENTORY_SLOT_BAG_START][j] < pProto->GetMaxStackSize())
|
||||
{
|
||||
pItem2 = GetItemByPos(t, j);
|
||||
if (pItem2 && pItem2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inv_bags[t - INVENTORY_SLOT_BAG_START][j] + pItem->GetCount() <= pProto->GetMaxStackSize())
|
||||
{
|
||||
inv_bags[t - INVENTORY_SLOT_BAG_START][j] += pItem->GetCount();
|
||||
b_found = true;
|
||||
// add count to stack so that later items in the list do not double-book
|
||||
bagCounts[t - INVENTORY_SLOT_BAG_START][j] += remaining_count;
|
||||
remaining_count =
|
||||
bagCounts[t - INVENTORY_SLOT_BAG_START][j] < pProto->GetMaxStackSize() ? 0 : bagCounts[t - INVENTORY_SLOT_BAG_START][j] - pProto->GetMaxStackSize();
|
||||
|
||||
b_found = remaining_count == 0;
|
||||
|
||||
// if no pieces of the stack remain, then stop checking equippable bags
|
||||
if (b_found)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
}
|
||||
@@ -1690,9 +1744,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
uint32 keyringSize = GetMaxKeyringSize();
|
||||
for (uint32 t = KEYRING_SLOT_START; t < KEYRING_SLOT_START + keyringSize; ++t)
|
||||
{
|
||||
if (inv_keys[t - KEYRING_SLOT_START] == 0)
|
||||
if (keyringCounts[t - KEYRING_SLOT_START] == 0)
|
||||
{
|
||||
inv_keys[t - KEYRING_SLOT_START] = 1;
|
||||
keyringCounts[t - KEYRING_SLOT_START] = remaining_count;
|
||||
keyringPointers[t - KEYRING_SLOT_START] = item;
|
||||
|
||||
b_found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1706,9 +1762,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
{
|
||||
for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
|
||||
{
|
||||
if (inv_tokens[t - CURRENCYTOKEN_SLOT_START] == 0)
|
||||
if (currencyCounts[t - CURRENCYTOKEN_SLOT_START] == 0)
|
||||
{
|
||||
inv_tokens[t - CURRENCYTOKEN_SLOT_START] = 1;
|
||||
currencyCounts[t - CURRENCYTOKEN_SLOT_START] = remaining_count;
|
||||
currencyPointers[t - CURRENCYTOKEN_SLOT_START] = item;
|
||||
|
||||
b_found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1725,14 +1783,15 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
pBagProto = bag->GetTemplate();
|
||||
|
||||
// not plain container check
|
||||
if (pBagProto && (pBagProto->Class != ITEM_CLASS_CONTAINER || pBagProto->SubClass != ITEM_SUBCLASS_CONTAINER) &&
|
||||
ItemCanGoIntoBag(pProto, pBagProto))
|
||||
if (pBagProto && (pBagProto->Class != ITEM_CLASS_CONTAINER || pBagProto->SubClass != ITEM_SUBCLASS_CONTAINER) && ItemCanGoIntoBag(pProto, pBagProto))
|
||||
{
|
||||
for (uint32 j = 0; j < bag->GetBagSize(); j++)
|
||||
{
|
||||
if (inv_bags[t - INVENTORY_SLOT_BAG_START][j] == 0)
|
||||
if (bagCounts[t - INVENTORY_SLOT_BAG_START][j] == 0)
|
||||
{
|
||||
inv_bags[t - INVENTORY_SLOT_BAG_START][j] = 1;
|
||||
bagCounts[t - INVENTORY_SLOT_BAG_START][j] = remaining_count;
|
||||
bagPointers[t - INVENTORY_SLOT_BAG_START][j] = item;
|
||||
|
||||
b_found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1740,6 +1799,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
}
|
||||
@@ -1748,18 +1808,21 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
bool b_found = false;
|
||||
for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t)
|
||||
{
|
||||
if (inv_slot_items[t - INVENTORY_SLOT_ITEM_START] == 0)
|
||||
if (inventoryCounts[t - INVENTORY_SLOT_ITEM_START] == 0)
|
||||
{
|
||||
inv_slot_items[t - INVENTORY_SLOT_ITEM_START] = 1;
|
||||
inventoryCounts[t - INVENTORY_SLOT_ITEM_START] = remaining_count;
|
||||
inventoryPointers[t - INVENTORY_SLOT_ITEM_START] = item;
|
||||
|
||||
b_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (b_found)
|
||||
continue;
|
||||
|
||||
// search free slot in bags
|
||||
for (int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t)
|
||||
for (uint8 t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; ++t)
|
||||
{
|
||||
if (Bag* bag = GetBagByPos(t))
|
||||
{
|
||||
@@ -1771,9 +1834,11 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
|
||||
for (uint32 j = 0; j < bag->GetBagSize(); j++)
|
||||
{
|
||||
if (inv_bags[t - INVENTORY_SLOT_BAG_START][j] == 0)
|
||||
if (bagCounts[t - INVENTORY_SLOT_BAG_START][j] == 0)
|
||||
{
|
||||
inv_bags[t - INVENTORY_SLOT_BAG_START][j] = 1;
|
||||
bagCounts[t - INVENTORY_SLOT_BAG_START][j] = remaining_count;
|
||||
bagPointers[t - INVENTORY_SLOT_BAG_START][j] = item;
|
||||
|
||||
b_found = true;
|
||||
break;
|
||||
}
|
||||
@@ -1781,9 +1846,9 @@ InventoryResult Player::CanStoreItems(Item** pItems, int32 count) const
|
||||
}
|
||||
}
|
||||
|
||||
// no free slot found?
|
||||
// if no free slot found for all pieces of the item, then return an error
|
||||
if (!b_found)
|
||||
return EQUIP_ERR_INVENTORY_FULL;
|
||||
return EQUIP_ERR_BAG_FULL;
|
||||
}
|
||||
|
||||
return EQUIP_ERR_OK;
|
||||
|
||||
@@ -1177,9 +1177,6 @@ bool Player::UpdatePosition(float x, float y, float z, float orientation,
|
||||
if (GetGroup())
|
||||
SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION);
|
||||
|
||||
if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE))
|
||||
GetSession()->SendCancelTrade(TRADE_STATUS_TRADE_CANCELED);
|
||||
|
||||
CheckAreaExploreAndOutdoor();
|
||||
|
||||
return true;
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
|
||||
TradeData* TradeData::GetTraderData() const
|
||||
{
|
||||
return m_trader->GetTradeData();
|
||||
return _trader->GetTradeData();
|
||||
}
|
||||
|
||||
Item* TradeData::GetItem(TradeSlots slot) const
|
||||
{
|
||||
return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : nullptr;
|
||||
return m_items[slot] ? _player->GetItemByGuid(m_items[slot]) : nullptr;
|
||||
}
|
||||
|
||||
bool TradeData::HasItem(ObjectGuid itemGuid) const
|
||||
@@ -48,7 +48,7 @@ TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const
|
||||
|
||||
Item* TradeData::GetSpellCastItem() const
|
||||
{
|
||||
return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : nullptr;
|
||||
return m_spellCastItem ? _player->GetItemByGuid(m_spellCastItem) : nullptr;
|
||||
}
|
||||
|
||||
void TradeData::SetItem(TradeSlots slot, Item* item)
|
||||
@@ -92,16 +92,19 @@ void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= nullptr*/)
|
||||
|
||||
void TradeData::SetMoney(uint32 money)
|
||||
{
|
||||
if (m_money == money)
|
||||
if (_money == money)
|
||||
return;
|
||||
|
||||
if (!m_player->HasEnoughMoney(money))
|
||||
if (!_player->HasEnoughMoney(money))
|
||||
{
|
||||
m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BUSY);
|
||||
TradeStatusInfo info;
|
||||
info.Status = TRADE_STATUS_CLOSE_WINDOW;
|
||||
info.Result = EQUIP_ERR_NOT_ENOUGH_MONEY;
|
||||
_player->GetSession()->SendTradeStatus(info);
|
||||
return;
|
||||
}
|
||||
|
||||
m_money = money;
|
||||
_money = money;
|
||||
|
||||
SetAccepted(false);
|
||||
GetTraderData()->SetAccepted(false);
|
||||
@@ -112,20 +115,22 @@ void TradeData::SetMoney(uint32 money)
|
||||
void TradeData::Update(bool forTarget /*= true*/)
|
||||
{
|
||||
if (forTarget)
|
||||
m_trader->GetSession()->SendUpdateTrade(true); // player state for trader
|
||||
_trader->GetSession()->SendUpdateTrade(true); // player state for trader
|
||||
else
|
||||
m_player->GetSession()->SendUpdateTrade(false); // player state for player
|
||||
_player->GetSession()->SendUpdateTrade(false); // player state for player
|
||||
}
|
||||
|
||||
void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
|
||||
void TradeData::SetAccepted(bool state, bool forTrader /*= false*/)
|
||||
{
|
||||
m_accepted = state;
|
||||
_accepted = state;
|
||||
|
||||
if (!state)
|
||||
{
|
||||
if (crosssend)
|
||||
m_trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||
TradeStatusInfo info;
|
||||
info.Status = TRADE_STATUS_BACK_TO_TRADE;
|
||||
if (forTrader)
|
||||
_trader->GetSession()->SendTradeStatus(info);
|
||||
else
|
||||
m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE);
|
||||
_player->GetSession()->SendTradeStatus(info);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ class AC_GAME_API TradeData
|
||||
{
|
||||
public: // constructors
|
||||
TradeData(Player* player, Player* trader) :
|
||||
m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false), m_money(0), m_spell(0) { }
|
||||
_player(player), _trader(trader), _accepted(false), m_acceptProccess(false), _money(0), m_spell(0) { }
|
||||
|
||||
[[nodiscard]] Player* GetTrader() const { return m_trader; }
|
||||
[[nodiscard]] Player* GetTrader() const { return _trader; }
|
||||
[[nodiscard]] TradeData* GetTraderData() const;
|
||||
|
||||
[[nodiscard]] Item* GetItem(TradeSlots slot) const;
|
||||
@@ -52,11 +52,11 @@ public: // constructors
|
||||
[[nodiscard]] Item* GetSpellCastItem() const;
|
||||
[[nodiscard]] bool HasSpellCastItem() const { return m_spellCastItem; }
|
||||
|
||||
[[nodiscard]] uint32 GetMoney() const { return m_money; }
|
||||
[[nodiscard]] uint32 GetMoney() const { return _money; }
|
||||
void SetMoney(uint32 money);
|
||||
|
||||
[[nodiscard]] bool IsAccepted() const { return m_accepted; }
|
||||
void SetAccepted(bool state, bool crosssend = false);
|
||||
[[nodiscard]] bool IsAccepted() const { return _accepted; }
|
||||
void SetAccepted(bool state, bool forTrader = false);
|
||||
|
||||
[[nodiscard]] bool IsInAcceptProcess() const { return m_acceptProccess; }
|
||||
void SetInAcceptProcess(bool state) { m_acceptProccess = state; }
|
||||
@@ -65,13 +65,13 @@ private: // internal functions
|
||||
void Update(bool for_trader = true);
|
||||
|
||||
private: // fields
|
||||
Player* m_player; // Player who own of this TradeData
|
||||
Player* m_trader; // Player who trade with m_player
|
||||
Player* _player; // Player who own of this TradeData
|
||||
Player* _trader; // Player who trade with m_player
|
||||
|
||||
bool m_accepted; // m_player press accept for trade list
|
||||
bool _accepted; // m_player press accept for trade list
|
||||
bool m_acceptProccess; // one from player/trader press accept and this processed
|
||||
|
||||
uint32 m_money; // m_player place money to trade
|
||||
uint32 _money; // m_player place money to trade
|
||||
|
||||
uint32 m_spell; // m_player apply spell to non-traded slot item
|
||||
ObjectGuid m_spellCastItem; // applied spell casted by item use
|
||||
|
||||
Reference in New Issue
Block a user