TrinityCore
Loading...
Searching...
No Matches
BankHandler.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "WorldSession.h"
19#include "BankPackets.h"
20#include "Chat.h"
21#include "Creature.h"
22#include "DB2Stores.h"
23#include "GossipDef.h"
24#include "Item.h"
25#include "Language.h"
26#include "Log.h"
27#include "NPCPackets.h"
28#include "Player.h"
29
31{
32 TC_LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
33
34 if (!CanUseBank())
35 {
36 TC_LOG_ERROR("network", "WORLD: HandleAutoBankItemOpcode - Unit ({}) not found or you can't interact with him.", _player->PlayerTalkClass->GetInteractionData().SourceGuid);
37 return;
38 }
39
40 if (packet.BankType != BankType::Character)
41 return;
42
43 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
44 if (!item)
45 return;
46
47 ItemPosCountVec dest;
48 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
49 if (msg != EQUIP_ERR_OK)
50 {
51 _player->SendEquipError(msg, item, nullptr);
52 return;
53 }
54
55 if (dest.size() == 1 && dest[0].pos == item->GetPos())
56 {
58 return;
59 }
60
61 _player->RemoveItem(packet.Bag, packet.Slot, true);
63 _player->BankItem(dest, item, true);
64}
65
67{
69 return;
70
72 if (!unit)
73 {
74 TC_LOG_ERROR("network", "WORLD: HandleBankerActivateOpcode - {} not found or you can not interact with him.", bankerActivate.Banker);
75 return;
76 }
77
78 switch (bankerActivate.InteractionType)
79 {
82 return;
83 break;
86 return;
87 break;
90 return;
91 break;
92 default:
93 break;
94 }
95
96 // remove fake death
97 if (GetPlayer()->HasUnitState(UNIT_STATE_DIED))
99
100 // set currentBankerGUID for other bank action
101
102 SendShowBank(bankerActivate.Banker, bankerActivate.InteractionType);
103}
104
106{
107 TC_LOG_DEBUG("network", "STORAGE: receive bag = {}, slot = {}", packet.Bag, packet.Slot);
108
109 if (!CanUseBank())
110 {
111 TC_LOG_ERROR("network", "WORLD: HandleAutoStoreBankItemOpcode - Unit ({}) not found or you can't interact with him.", _player->PlayerTalkClass->GetInteractionData().SourceGuid);
112 return;
113 }
114
115 Item* item = _player->GetItemByPos(packet.Bag, packet.Slot);
116 if (!item)
117 return;
118
119 if (_player->IsBankPos(packet.Bag, packet.Slot)) // moving from bank to inventory
120 {
121 ItemPosCountVec dest;
122 InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, item, false);
123 if (msg != EQUIP_ERR_OK)
124 {
125 _player->SendEquipError(msg, item, nullptr);
126 return;
127 }
128
129 _player->RemoveItem(packet.Bag, packet.Slot, true);
130 if (Item const* storedItem = _player->StoreItem(dest, item, true))
131 _player->ItemAddedQuestCheck(storedItem->GetEntry(), storedItem->GetCount());
132
133 }
134 else // moving from inventory to bank
135 {
136 ItemPosCountVec dest;
137 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false);
138 if (msg != EQUIP_ERR_OK)
139 {
140 _player->SendEquipError(msg, item, nullptr);
141 return;
142 }
143
144 _player->RemoveItem(packet.Bag, packet.Slot, true);
145 _player->BankItem(dest, item, true);
146 }
147}
148
150{
151 if (!CanUseBank(buyBankTab.Banker))
152 {
153 TC_LOG_ERROR("network", "WorldSession::HandleBuyBankTab {} - Banker {} not found or can't interact with him.",
154 _player->GetGUID(), buyBankTab.Banker);
155 return;
156 }
157
158 if (buyBankTab.BankType != BankType::Character)
159 {
160 TC_LOG_DEBUG("network", "WorldSession::HandleBuyBankTab {} - Bank type {} is not supported.",
161 _player->GetGUID(), buyBankTab.BankType);
162 return;
163 }
164
165 uint32 itemId = 0;
166 uint8 slot = 0;
167 uint8 inventorySlot = 0;
168
169 switch (buyBankTab.BankType)
170 {
174 inventorySlot = BANK_SLOT_BAG_START + slot;
175 break;
179 inventorySlot = ACCOUNT_BANK_SLOT_BAG_START + slot;
180 break;
181 default:
182 TC_LOG_DEBUG("network", "WorldSession::HandleBuyBankTab {} - Bank type {} is not supported.",
183 _player->GetGUID(), buyBankTab.BankType);
184 return;
185 }
186
187 auto bankTab = std::ranges::find(sBankTabStore, std::pair(buyBankTab.BankType, int8(slot)),
188 [](BankTabEntry const* bankTab) { return std::pair(BankType(bankTab->BankType), bankTab->OrderIndex); });
189
190 if (bankTab == sBankTabStore.end())
191 return;
192
193 uint64 price = bankTab->Cost;
194 if (!_player->HasEnoughMoney(price))
195 return;
196
197 uint16 inventoryPos = 0;
198 InventoryResult msg = _player->CanEquipNewItem(inventorySlot, inventoryPos, itemId, false);
199 if (msg != EQUIP_ERR_OK)
200 {
201 _player->SendEquipError(msg, nullptr, nullptr, itemId);
202 return;
203 }
204
205 Item* bag = _player->EquipNewItem(inventoryPos, itemId, ItemContext::NONE, true);
206 if (!bag)
207 return;
208
209 switch (buyBankTab.BankType)
210 {
214 break;
218 break;
219 default:
220 break;
221 }
222
223 _player->ModifyMoney(-int64(price));
224
226}
227
229{
230 if (!CanUseBank(updateBankTabSettings.Banker))
231 {
232 TC_LOG_ERROR("network", "WorldSession::HandleUpdateBankTabSettings {} - Banker {} not found or can't interact with him.",
233 _player->GetGUID(), updateBankTabSettings.Banker);
234 return;
235 }
236
237 switch (updateBankTabSettings.BankType)
238 {
240 if (updateBankTabSettings.Tab >= _player->m_activePlayerData->CharacterBankTabSettings.size())
241 {
242 TC_LOG_DEBUG("network", "WorldSession::HandleUpdateBankTabSettings {} doesn't have bank tab {} in bank type {}.",
243 _player->GetGUID(), updateBankTabSettings.Tab, updateBankTabSettings.BankType);
244 return;
245 }
246 _player->SetCharacterBankTabSettings(updateBankTabSettings.Tab, updateBankTabSettings.Settings.Name,
247 updateBankTabSettings.Settings.Icon, updateBankTabSettings.Settings.Description, updateBankTabSettings.Settings.DepositFlags);
248 break;
250 if (updateBankTabSettings.Tab >= _player->m_activePlayerData->AccountBankTabSettings.size())
251 {
252 TC_LOG_DEBUG("network", "WorldSession::HandleUpdateBankTabSettings {} doesn't have bank tab {} in bank type {}.",
253 _player->GetGUID(), updateBankTabSettings.Tab, updateBankTabSettings.BankType);
254 return;
255 }
256 _player->SetAccountBankTabSettings(updateBankTabSettings.Tab, updateBankTabSettings.Settings.Name,
257 updateBankTabSettings.Settings.Icon, updateBankTabSettings.Settings.Description, updateBankTabSettings.Settings.DepositFlags);
258 break;
259 default:
260 TC_LOG_DEBUG("network", "WorldSession::HandleUpdateBankTabSettings {} - Bank type {} is not supported.",
261 _player->GetGUID(), updateBankTabSettings.BankType);
262 break;
263 }
264}
265
267{
268 if (!CanUseBank(autoDepositCharacterBank.Banker))
269 {
270 TC_LOG_DEBUG("network", "WORLD: HandleReagentBankDepositOpcode - {} not found or you can't interact with him.", autoDepositCharacterBank.Banker);
271 return;
272 }
273
275 {
277 return;
278 }
279
280 // query all reagents from player's inventory
281 bool anyDeposited = false;
283 {
284 ItemPosCountVec dest;
285 InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false, true, true);
286 if (msg != EQUIP_ERR_OK)
287 {
288 if (msg != EQUIP_ERR_REAGENT_BANK_FULL || !anyDeposited)
289 _player->SendEquipError(msg, item, nullptr);
290 break;
291 }
292
293 if (dest.size() == 1 && dest[0].pos == item->GetPos())
294 {
296 continue;
297 }
298
299 // store reagent
300 _player->RemoveItem(item->GetBagSlot(), item->GetSlot(), true);
301 _player->BankItem(dest, item, true);
302 anyDeposited = true;
303 }
304}
305
307{
308 _player->PlayerTalkClass->GetInteractionData().StartInteraction(guid, interactionType);
309
311 npcInteraction.Npc = guid;
312 npcInteraction.InteractionType = interactionType;
313 npcInteraction.Success = true;
314 SendPacket(npcInteraction.Write());
315}
DB2Storage< BankTabEntry > sBankTabStore("BankTab.db2", &BankTabLoadInfo::Instance)
PlayerInteractionType
Definition DBCEnums.h:2211
uint8_t uint8
Definition Define.h:156
int64_t int64
Definition Define.h:149
int8_t int8
Definition Define.h:152
uint64_t uint64
Definition Define.h:153
uint16_t uint16
Definition Define.h:155
uint32_t uint32
Definition Define.h:154
InventoryResult
Definition ItemDefines.h:25
@ EQUIP_ERR_REAGENT_BANK_FULL
@ EQUIP_ERR_REAGENT_BANK_LOCKED
@ EQUIP_ERR_OK
Definition ItemDefines.h:26
@ EQUIP_ERR_CANT_SWAP
Definition ItemDefines.h:47
BankType
@ ITEM_ACCOUNT_BANK_TAB_BAG
@ ITEM_CHARACTER_BANK_TAB_BAG
@ LANG_BANK_TAB_NAME
Definition Language.h:765
#define TC_LOG_DEBUG(filterType__, message__,...)
Definition Log.h:181
#define TC_LOG_ERROR(filterType__, message__,...)
Definition Log.h:190
std::vector< ItemPosCount > ItemPosCountVec
Definition Player.h:841
@ BANK_SLOT_BAG_START
Definition Player.h:791
@ ACCOUNT_BANK_SLOT_BAG_START
Definition Player.h:830
@ SPELL_AURA_FEIGN_DEATH
@ UNIT_NPC_FLAG_BANKER
@ UNIT_NPC_FLAG_ACCOUNT_BANKER
@ UNIT_NPC_FLAG_2_NONE
@ UNIT_STATE_DIED
Definition Unit.h:261
@ NULL_BAG
Definition Unit.h:63
@ NULL_SLOT
Definition Unit.h:64
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
static std::string PGetParseString(std::string_view fmt, Args &&... args) noexcept
Definition Chat.h:74
Definition Item.h:179
uint16 GetPos() const
Definition Item.h:294
uint32 GetCount() const
Definition Item.h:283
uint32 GetEntry() const
Definition Object.h:89
void SendEquipError(InventoryResult msg, Item const *item1=nullptr, Item const *item2=nullptr, uint32 itemId=0) const
Definition Player.cpp:13130
void ItemRemovedQuestCheck(uint32 entry, uint32 count)
Definition Player.cpp:16640
void SetCharacterBankTabSettings(uint32 tabId, std::string const &name, std::string const &icon, std::string const &description, BagSlotFlags depositFlags)
Definition Player.h:1507
bool ModifyMoney(int64 amount, bool sendError=true)
Definition Player.cpp:24850
InventoryResult CanEquipNewItem(uint8 slot, uint16 &dest, uint32 item, bool swap) const
Definition Player.cpp:10774
Creature * GetNPCIfCanInteractWith(ObjectGuid const &guid, NPCFlags npcFlags, NPCFlags2 npcFlags2) const
Definition Player.cpp:1903
void SetCharacterBankTabCount(uint8 count)
Definition Player.h:1504
Item * BankItem(ItemPosCountVec const &dest, Item *pItem, bool update)
Definition Player.cpp:11984
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Definition Player.h:3062
InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap=false) const
Definition Player.cpp:10055
uint8 GetCharacterBankTabCount() const
Definition Player.h:1503
Item * EquipNewItem(uint16 pos, uint32 item, ItemContext context, bool update)
Definition Player.cpp:11576
InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item *pItem, bool swap, bool not_loading=true, bool reagentBankOnly=false) const
Definition Player.cpp:11064
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition Player.cpp:11447
Item * GetItemByPos(uint16 pos) const
Definition Player.cpp:9630
uint8 GetAccountBankTabCount() const
Definition Player.h:1505
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
Definition Player.cpp:27588
std::vector< Item * > GetCraftingReagentItemsToDeposit()
Definition Player.cpp:9600
bool IsReagentBankUnlocked() const
Definition Player.h:2878
void ItemAddedQuestCheck(uint32 entry, uint32 count, Optional< bool > boundItemFlagRequirement={}, bool *hadBoundItemObjective=nullptr)
Definition Player.cpp:16599
void SetAccountBankTabCount(uint8 count)
Definition Player.h:1506
static bool IsBankPos(uint16 pos)
Definition Player.h:1491
void RemoveItem(uint8 bag, uint8 slot, bool update)
Definition Player.cpp:11989
std::unique_ptr< PlayerMenu > PlayerTalkClass
Definition Player.h:2570
bool HasEnoughMoney(uint64 amount) const
Definition Player.h:1907
void SetAccountBankTabSettings(uint32 tabId, std::string const &name, std::string const &icon, std::string const &description, BagSlotFlags depositFlags)
Definition Player.h:1512
void RemoveAurasByType(AuraType auraType, std::function< bool(AuraApplication const *)> const &check, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3955
bool HasNpcFlag(NPCFlags flags) const
Definition Unit.h:996
PlayerInteractionType InteractionType
Definition BankPackets.h:86
WorldPacket const * Write() override
void HandleBankerActivateOpcode(WorldPackets::Bank::BankerActivate const &bankerActivate)
Player * GetPlayer() const
void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType)
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
void HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem &packet)
Player * _player
void HandleBuyBankTab(WorldPackets::Bank::BuyBankTab const &buyBankTab)
bool CanUseBank(ObjectGuid bankerGUID=ObjectGuid::Empty) const
void HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem &packet)
void HandleAutoDepositCharacterBank(WorldPackets::Bank::AutoDepositCharacterBank const &autoDepositCharacterBank)
void HandleUpdateBankTabSettings(WorldPackets::Bank::UpdateBankTabSettings const &updateBankTabSettings)