Core/Players: Fixed buying bank tabs

This commit is contained in:
Shauren
2025-09-01 00:11:04 +02:00
parent 629d845ae9
commit 8b2fc59397
5 changed files with 45 additions and 38 deletions

View File

@@ -0,0 +1,3 @@
DELETE FROM `trinity_string` WHERE `entry`=810;
INSERT INTO `trinity_string` (`entry`,`content_default`) VALUES
(810,'Tab %u');

View File

@@ -9249,9 +9249,9 @@ void Player::SendRespecWipeConfirm(ObjectGuid const& guid, uint32 cost, SpecRese
/*** STORAGE SYSTEM ***/
/*********************************************************/
uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const
uint8 Player::FindEquipSlot(Item const* item, uint8 slot, bool swap) const
{
std::array<uint8, 4> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT };
std::array<uint8, 6> slots = { NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT, NULL_SLOT };
switch (item->GetTemplate()->GetInventoryType())
{
case INVTYPE_HEAD:
@@ -9335,8 +9335,12 @@ uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const
slots[0] = EQUIPMENT_SLOT_MAINHAND;
break;
case INVTYPE_BAG:
if (item->GetTemplate()->GetClass() != ITEM_CLASS_CONTAINER || item->GetTemplate()->GetSubClass() != ITEM_SUBCLASS_REAGENT_CONTAINER)
slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3 };
if (item->GetTemplate()->GetId() == ITEM_ACCOUNT_BANK_TAB_BAG)
slots = { ACCOUNT_BANK_SLOT_BAG_START + 0, ACCOUNT_BANK_SLOT_BAG_START + 1, ACCOUNT_BANK_SLOT_BAG_START + 2, ACCOUNT_BANK_SLOT_BAG_START + 3, ACCOUNT_BANK_SLOT_BAG_START + 4, NULL_SLOT };
else if (item->GetTemplate()->GetId() == ITEM_CHARACTER_BANK_TAB_BAG)
slots = { BANK_SLOT_BAG_START + 0, BANK_SLOT_BAG_START + 1, BANK_SLOT_BAG_START + 2, BANK_SLOT_BAG_START + 3, BANK_SLOT_BAG_START + 4, BANK_SLOT_BAG_START + 5 };
else if (item->GetTemplate()->GetClass() != ITEM_CLASS_CONTAINER || item->GetTemplate()->GetSubClass() != ITEM_SUBCLASS_REAGENT_CONTAINER)
slots = { INVENTORY_SLOT_BAG_START + 0, INVENTORY_SLOT_BAG_START + 1, INVENTORY_SLOT_BAG_START + 2, INVENTORY_SLOT_BAG_START + 3, NULL_SLOT, NULL_SLOT };
else
slots[0] = REAGENT_BAG_SLOT_START;
break;
@@ -9406,41 +9410,40 @@ uint8 Player::FindEquipSlot(Item const* item, uint32 slot, bool swap) const
if (slot != NULL_SLOT)
{
if (swap || !GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
for (uint8 i = 0; i < 4; ++i)
if (slots[i] == slot)
return slot;
if (advstd::ranges::contains(slots, slot))
return slot;
}
else
{
// search free slot at first
for (uint8 i = 0; i < 4; ++i)
if (slots[i] != NULL_SLOT && !GetItemByPos(INVENTORY_SLOT_BAG_0, slots[i]))
auto slotItr = std::ranges::find_if(slots, [&](uint8 candidateSlot)
{
if (candidateSlot != NULL_SLOT && !GetItemByPos(INVENTORY_SLOT_BAG_0, candidateSlot))
// in case 2hand equipped weapon (without titan grip) offhand slot empty but not free
if (slots[i] != EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed())
return slots[i];
if (candidateSlot != EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed())
return true;
return false;
});
if (slotItr != slots.end())
return *slotItr;
// if not found free and can swap return slot with lower item level equipped
if (swap)
{
uint32 minItemLevel = std::numeric_limits<uint32>::max();
uint8 minItemLevelIndex = 0;
for (uint8 i = 0; i < 4; ++i)
slotItr = std::ranges::min_element(slots, std::ranges::less(), [&](uint8 candidateSlot)
{
if (slots[i] != NULL_SLOT)
{
if (Item const* equipped = GetItemByPos(INVENTORY_SLOT_BAG_0, slots[i]))
{
uint32 itemLevel = equipped->GetItemLevel(this);
if (itemLevel < minItemLevel)
{
minItemLevel = itemLevel;
minItemLevelIndex = i;
}
}
}
}
if (candidateSlot == NULL_SLOT)
return std::numeric_limits<uint32>::max();
return slots[minItemLevelIndex];
if (Item const* equipped = GetItemByPos(INVENTORY_SLOT_BAG_0, candidateSlot))
return equipped->GetItemLevel(this);
return 0u;
});
if (slotItr != slots.end())
return *slotItr;
}
}

View File

@@ -1386,7 +1386,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
void UpdateAverageItemLevelTotal();
void UpdateAverageItemLevelEquipped();
uint8 FindEquipSlot(Item const* item, uint32 slot, bool swap) const;
uint8 FindEquipSlot(Item const* item, uint8 slot, bool swap) const;
uint32 GetFreeInventorySlotCount(EnumFlag<ItemSearchLocation> location = ItemSearchLocation::Inventory) const;
uint32 GetItemCount(uint32 item, bool inBankAlso = false, Item* skipItem = nullptr) const;
uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const;
@@ -1434,7 +1434,7 @@ class TC_GAME_API Player final : public Unit, public GridObject<Player>
auto setter = m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::AccountBankTabSettings, tabId);
SetBankTabSettings(setter, name, icon, description, depositFlags);
}
void SetBankTabSettings(UF::MutableFieldReferenceWithChangesMask<UF::BankTabSettings, false> setter, std::string const& name, std::string const& icon, std::string const& description, BagSlotFlags depositFlags)
void SetBankTabSettings(UF::MutableFieldReferenceWithChangesMask<UF::BankTabSettings, false> setter, std::string const& name, std::string const& icon, std::string const& description, BagSlotFlags depositFlags)
{
SetUpdateFieldValue(setter.ModifyValue(&UF::BankTabSettings::Name), name);
SetUpdateFieldValue(setter.ModifyValue(&UF::BankTabSettings::Icon), icon);

View File

@@ -17,10 +17,12 @@
#include "WorldSession.h"
#include "BankPackets.h"
#include "Chat.h"
#include "Creature.h"
#include "DB2Stores.h"
#include "GossipDef.h"
#include "Item.h"
#include "Language.h"
#include "Log.h"
#include "NPCPackets.h"
#include "Player.h"
@@ -169,12 +171,12 @@ void WorldSession::HandleBuyBankTab(WorldPackets::Bank::BuyBankTab const& buyBan
case BankType::Character:
itemId = ITEM_CHARACTER_BANK_TAB_BAG;
slot = _player->GetCharacterBankTabCount();
inventorySlot = BANK_SLOT_BAG_START;
inventorySlot = BANK_SLOT_BAG_START + slot;
break;
case BankType::Account:
itemId = ITEM_ACCOUNT_BANK_TAB_BAG;
slot = _player->GetAccountBankTabCount();
inventorySlot = ACCOUNT_BANK_SLOT_BAG_START;
inventorySlot = ACCOUNT_BANK_SLOT_BAG_START + slot;
break;
default:
TC_LOG_DEBUG("network", "WorldSession::HandleBuyBankTab {} - Bank type {} is not supported.",
@@ -182,9 +184,6 @@ void WorldSession::HandleBuyBankTab(WorldPackets::Bank::BuyBankTab const& buyBan
return;
}
// next slot
++slot;
auto bankTab = std::ranges::find(sBankTabStore, std::pair(buyBankTab.BankType, int8(slot)),
[](BankTabEntry const* bankTab) { return std::pair(BankType(bankTab->BankType), bankTab->OrderIndex); });
@@ -210,10 +209,12 @@ void WorldSession::HandleBuyBankTab(WorldPackets::Bank::BuyBankTab const& buyBan
switch (buyBankTab.BankType)
{
case BankType::Character:
_player->SetCharacterBankTabCount(slot);
_player->SetCharacterBankTabCount(slot + 1);
_player->SetCharacterBankTabSettings(slot, ChatHandler(this).PGetParseString(LANG_BANK_TAB_NAME, slot + 1), "", "", BagSlotFlags::None);
break;
case BankType::Account:
_player->SetAccountBankTabCount(slot);
_player->SetAccountBankTabCount(slot + 1);
_player->SetAccountBankTabSettings(slot, ChatHandler(this).PGetParseString(LANG_BANK_TAB_NAME, slot + 1), "", "", BagSlotFlags::None);
break;
default:
break;

View File

@@ -762,7 +762,7 @@ enum TrinityStrings
LANG_NEED_CHARACTER_NAME = 807,
LANG_PLAYER_NOT_EXIST_OR_OFFLINE = 808,
LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND = 809,
// unused = 810,
LANG_BANK_TAB_NAME = 810,
LANG_GUILD_MASTER = 811,
LANG_GUILD_OFFICER = 812,
LANG_GUILD_VETERAN = 813,