aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp201
-rw-r--r--src/server/game/Entities/Player/Player.h9
-rw-r--r--src/server/game/Handlers/BankHandler.cpp148
-rw-r--r--src/server/game/Server/Packets/BankPackets.cpp19
-rw-r--r--src/server/game/Server/Packets/BankPackets.h36
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp8
-rw-r--r--src/server/game/Server/WorldSession.h7
-rw-r--r--src/server/scripts/Commands/cs_list.cpp2
8 files changed, 312 insertions, 118 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index cc8d0c96ff8..aabbb560cf3 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -10080,6 +10080,20 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte
return count;
}
+std::vector<Item*> Player::GetCraftingReagentItemsToDeposit()
+{
+ std::vector<Item*> itemList = std::vector<Item*>();
+ ForEachItem(ItemSearchLocation::Inventory, [&itemList](Item* item)
+ {
+ if (item->GetTemplate()->IsCraftingReagent())
+ itemList.push_back(item);
+
+ return ItemSearchCallbackResult::Continue;
+ });
+
+ return itemList;
+}
+
Item* Player::GetItemByGuid(ObjectGuid guid) const
{
Item* result = nullptr;
@@ -10237,8 +10251,6 @@ bool Player::IsInventoryPos(uint8 bag, uint8 slot)
return true;
if (bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END)
return true;
- if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_SLOT_START && slot < REAGENT_SLOT_END))
- return true;
if (bag == INVENTORY_SLOT_BAG_0 && (slot >= CHILD_EQUIPMENT_SLOT_START && slot < CHILD_EQUIPMENT_SLOT_END))
return true;
return false;
@@ -10261,6 +10273,15 @@ bool Player::IsBankPos(uint8 bag, uint8 slot)
return true;
if (bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END)
return true;
+ if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_SLOT_START && slot < REAGENT_SLOT_END))
+ return true;
+ return false;
+}
+
+bool Player::IsReagentBankPos(uint8 bag, uint8 slot)
+{
+ if (bag == INVENTORY_SLOT_BAG_0 && (slot >= REAGENT_SLOT_START && slot < REAGENT_SLOT_END))
+ return true;
return false;
}
@@ -10312,6 +10333,10 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const
if (slot >= BANK_SLOT_BAG_START && slot < BANK_SLOT_BAG_END)
return true;
+ // reagent bank bag slots
+ if (slot >= REAGENT_SLOT_START && slot < REAGENT_SLOT_END)
+ return true;
+
return false;
}
@@ -10559,13 +10584,6 @@ bool Player::HasItemTotemCategory(uint32 TotemCategory) const
}
}
- for (uint8 i = REAGENT_SLOT_START; i < REAGENT_SLOT_END; ++i)
- {
- item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i);
- if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory))
- return true;
- }
-
for (uint8 i = CHILD_EQUIPMENT_SLOT_START; i < CHILD_EQUIPMENT_SLOT_END; ++i)
{
item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i);
@@ -10606,6 +10624,10 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
// prevent cheating
if ((slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END) || slot >= PLAYER_SLOT_END)
return EQUIP_ERR_WRONG_BAG_TYPE;
+
+ // can't store anything else than crafting reagents in Reagent Bank
+ if (IsReagentBankPos(bag, slot) && (!IsReagentBankUnlocked() || !pProto->IsCraftingReagent()))
+ return EQUIP_ERR_WRONG_BAG_TYPE;
}
else
{
@@ -10871,24 +10893,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_ITEM_MAX_COUNT;
}
- res = CanStoreItem_InInventorySlots(REAGENT_SLOT_START, REAGENT_SLOT_END, dest, pProto, count, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_ITEM_MAX_COUNT;
- }
-
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
{
@@ -10956,26 +10960,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
- else if (pProto->IsCraftingReagent() && HasPlayerFlagEx(PLAYER_FLAGS_EX_REAGENT_BANK_UNLOCKED))
- {
- res = CanStoreItem_InInventorySlots(REAGENT_SLOT_START, REAGENT_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_ITEM_MAX_COUNT;
- }
- }
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
@@ -11043,24 +11027,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_ITEM_MAX_COUNT;
}
- res = CanStoreItem_InInventorySlots(REAGENT_SLOT_START, REAGENT_SLOT_END, dest, pProto, count, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_ITEM_MAX_COUNT;
- }
-
res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
{
@@ -11161,26 +11127,6 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_ITEM_MAX_COUNT;
}
}
- else if (pProto->IsCraftingReagent() && HasPlayerFlagEx(PLAYER_FLAGS_EX_REAGENT_BANK_UNLOCKED))
- {
- res = CanStoreItem_InInventorySlots(REAGENT_SLOT_START, REAGENT_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- {
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return res;
- }
-
- if (count == 0)
- {
- if (no_similar_count == 0)
- return EQUIP_ERR_OK;
-
- if (no_space_count)
- *no_space_count = count + no_similar_count;
- return EQUIP_ERR_ITEM_MAX_COUNT;
- }
- }
// search free slot
uint8 searchSlotStart = INVENTORY_SLOT_ITEM_START;
@@ -11718,11 +11664,23 @@ InventoryResult Player::CanUnequipItem(uint16 pos, bool swap) const
return EQUIP_ERR_OK;
}
-InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, Item* pItem, bool swap, bool not_loading) const
+InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap, bool not_loading /*= true*/, bool reagentBankOnly /*= false*/) const
{
if (!pItem)
return swap ? EQUIP_ERR_CANT_SWAP : EQUIP_ERR_ITEM_NOT_FOUND;
+ // different slots range if we're trying to store item in Reagent Bank
+ if (reagentBankOnly)
+ {
+ ASSERT(bag == NULL_BAG && slot == NULL_SLOT); // when reagentBankOnly is true then bag & slot must be hardcoded constants, not client input
+ }
+
+ if ((IsReagentBankPos(bag, slot) || reagentBankOnly) && !IsReagentBankUnlocked())
+ return EQUIP_ERR_REAGENT_BANK_LOCKED;
+
+ uint8 slotStart = reagentBankOnly ? uint8(REAGENT_SLOT_START) : uint8(BANK_SLOT_ITEM_START);
+ uint8 slotEnd = reagentBankOnly ? uint8(REAGENT_SLOT_END) : uint8(BANK_SLOT_ITEM_END);
+
uint32 count = pItem->GetCount();
TC_LOG_DEBUG("entities.player.items", "Player::CanBankItem: Player '%s' (%s), Bag: %u, Slot: %u, Item: %u, Count: %u",
@@ -11788,7 +11746,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
{
if (bag == INVENTORY_SLOT_BAG_0)
{
- res = CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START, BANK_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot);
+ res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
return res;
@@ -11812,7 +11770,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
// search free slot in bag
if (bag == INVENTORY_SLOT_BAG_0)
{
- res = CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START, BANK_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot);
+ res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
return res;
@@ -11839,19 +11797,34 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
if (pProto->GetMaxStackSize() != 1)
{
// in slots
- res = CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START, BANK_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot);
+ res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, count, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
return res;
if (count == 0)
return EQUIP_ERR_OK;
- // in special bags
- if (pProto->GetBagFamily())
+ // don't try to store reagents anywhere else than in Reagent Bank if we're on it
+ if (!reagentBankOnly)
{
+ // in special bags
+ if (pProto->GetBagFamily())
+ {
+ for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
+ {
+ res = CanStoreItem_InBag(i, dest, pProto, count, true, false, pItem, bag, slot);
+ if (res != EQUIP_ERR_OK)
+ continue;
+
+ if (count == 0)
+ return EQUIP_ERR_OK;
+ }
+ }
+
+ // in regular bags
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{
- res = CanStoreItem_InBag(i, dest, pProto, count, true, false, pItem, bag, slot);
+ res = CanStoreItem_InBag(i, dest, pProto, count, true, true, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
continue;
@@ -11859,20 +11832,10 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
return EQUIP_ERR_OK;
}
}
-
- for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
- {
- res = CanStoreItem_InBag(i, dest, pProto, count, true, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- continue;
-
- if (count == 0)
- return EQUIP_ERR_OK;
- }
}
- // search free place in special bag
- if (pProto->GetBagFamily())
+ // search free space in special bags (don't try to store reagents anywhere else than in Reagent Bank if we're on it)
+ if (!reagentBankOnly && pProto->GetBagFamily())
{
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
{
@@ -11886,23 +11849,28 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest
}
// search free space
- res = CanStoreItem_InInventorySlots(BANK_SLOT_ITEM_START, BANK_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot);
+ res = CanStoreItem_InInventorySlots(slotStart, slotEnd, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
return res;
if (count == 0)
return EQUIP_ERR_OK;
- for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
+ // search free space in regular bags (don't try to store reagents anywhere else than in Reagent Bank if we're on it)
+ if (!reagentBankOnly)
{
- res = CanStoreItem_InBag(i, dest, pProto, count, false, true, pItem, bag, slot);
- if (res != EQUIP_ERR_OK)
- continue;
+ for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)
+ {
+ res = CanStoreItem_InBag(i, dest, pProto, count, false, true, pItem, bag, slot);
+ if (res != EQUIP_ERR_OK)
+ continue;
- if (count == 0)
- return EQUIP_ERR_OK;
+ if (count == 0)
+ return EQUIP_ERR_OK;
+ }
}
- return EQUIP_ERR_BANK_FULL;
+
+ return reagentBankOnly ? EQUIP_ERR_REAGENT_BANK_FULL : EQUIP_ERR_BANK_FULL;
}
InventoryResult Player::CanUseItem(Item* pItem, bool not_loading) const
@@ -13396,6 +13364,12 @@ void Player::SwapItem(uint16 src, uint16 dst)
}
}
+ if (IsReagentBankPos(dst) && !IsReagentBankUnlocked())
+ {
+ SendEquipError(EQUIP_ERR_REAGENT_BANK_LOCKED, pSrcItem, pDstItem);
+ return;
+ }
+
// NOW this is or item move (swap with empty), or swap with another item (including bags in bag possitions)
// or swap empty bag with another empty or not empty bag (with items exchange)
@@ -13429,7 +13403,8 @@ void Player::SwapItem(uint16 src, uint16 dst)
RemoveItem(srcbag, srcslot, true);
BankItem(dest, pSrcItem, true);
- ItemRemovedQuestCheck(pSrcItem->GetEntry(), pSrcItem->GetCount());
+ if (!IsReagentBankPos(dst))
+ ItemRemovedQuestCheck(pSrcItem->GetEntry(), pSrcItem->GetCount());
}
else if (IsEquipmentPos(dst))
{
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 56d70c4eb11..965fbe7d00a 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1310,6 +1310,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
Item* GetItemByPos(uint8 bag, uint8 slot) const;
Item* GetUseableItemByPos(uint8 bag, uint8 slot) const;
Bag* GetBagByPos(uint8 slot) const;
+ std::vector<Item*> GetCraftingReagentItemsToDeposit();
uint32 GetFreeInventorySpace() const;
Item* GetWeaponForAttack(WeaponAttackType attackType, bool useable = false) const;
Item* GetShield(bool useable = false) const;
@@ -1323,6 +1324,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
static bool IsBagPos(uint16 pos);
static bool IsBankPos(uint16 pos) { return IsBankPos(pos >> 8, pos & 255); }
static bool IsBankPos(uint8 bag, uint8 slot);
+ static bool IsReagentBankPos(uint16 pos) { return IsReagentBankPos(pos >> 8, pos & 255); }
+ static bool IsReagentBankPos(uint8 bag, uint8 slot);
static bool IsChildEquipmentPos(uint16 pos) { return IsChildEquipmentPos(pos >> 8, pos & 255); }
static bool IsChildEquipmentPos(uint8 bag, uint8 slot);
bool IsValidPos(uint16 pos, bool explicit_pos) const { return IsValidPos(pos >> 8, pos & 255, explicit_pos); }
@@ -1357,7 +1360,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
InventoryResult CanEquipUniqueItem(ItemTemplate const* itemProto, uint8 except_slot = NULL_SLOT, uint32 limit_count = 1) const;
InventoryResult CanUnequipItems(uint32 item, uint32 count) const;
InventoryResult CanUnequipItem(uint16 src, bool swap) const;
- InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap, bool not_loading = true) const;
+ InventoryResult CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap, bool not_loading = true, bool reagentBankOnly = false) const;
InventoryResult CanUseItem(Item* pItem, bool not_loading = true) const;
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem, bool skipRequiredLevelCheck = false) const;
@@ -2589,6 +2592,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
VoidStorageItem* GetVoidStorageItem(uint8 slot) const;
VoidStorageItem* GetVoidStorageItem(uint64 id, uint8& slot) const;
+ // Reagent Bank
+ bool IsReagentBankUnlocked() const { return HasPlayerFlagEx(PLAYER_FLAGS_EX_REAGENT_BANK_UNLOCKED); }
+ void UnlockReagentBank() { AddPlayerFlagEx(PLAYER_FLAGS_EX_REAGENT_BANK_UNLOCKED); }
+
void CreateGarrison(uint32 garrSiteId);
void DeleteGarrison();
Garrison* GetGarrison() const { return _garrison.get(); }
diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp
index 6010b0afec3..a41144f2c89 100644
--- a/src/server/game/Handlers/BankHandler.cpp
+++ b/src/server/game/Handlers/BankHandler.cpp
@@ -150,6 +150,154 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& pack
_player->UpdateCriteria(CriteriaType::BankSlotsPurchased);
}
+void WorldSession::HandleBuyReagentBankOpcode(WorldPackets::Bank::ReagentBank& reagentBank)
+{
+ if (!CanUseBank(reagentBank.Banker))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleBuyReagentBankOpcode - %s not found or you can't interact with him.", reagentBank.Banker.ToString().c_str());
+ return;
+ }
+
+ if (_player->IsReagentBankUnlocked())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleBuyReagentBankOpcode - Player (%s, name: %s) tried to unlock reagent bank a 2nd time.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str());
+ return;
+ }
+
+ constexpr int64 price = 100 * GOLD;
+
+ if (!_player->HasEnoughMoney(price))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleBuyReagentBankOpcode - Player (%s, name: %s) without enough gold.", _player->GetGUID().ToString().c_str(), _player->GetName().c_str());
+ return;
+ }
+
+ _player->ModifyMoney(-price);
+ _player->UnlockReagentBank();
+}
+
+void WorldSession::HandleReagentBankDepositOpcode(WorldPackets::Bank::ReagentBank& reagentBank)
+{
+ if (!CanUseBank(reagentBank.Banker))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleReagentBankDepositOpcode - %s not found or you can't interact with him.", reagentBank.Banker.ToString().c_str());
+ return;
+ }
+
+ if (!_player->IsReagentBankUnlocked())
+ {
+ _player->SendEquipError(EQUIP_ERR_REAGENT_BANK_LOCKED);
+ return;
+ }
+
+ // query all reagents from player's inventory
+ bool anyDeposited = false;
+ for (Item* item : _player->GetCraftingReagentItemsToDeposit())
+ {
+ ItemPosCountVec dest;
+ InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false, true, true);
+ if (msg != EQUIP_ERR_OK)
+ {
+ if (msg != EQUIP_ERR_REAGENT_BANK_FULL || !anyDeposited)
+ _player->SendEquipError(msg, item, NULL);
+ break;
+ }
+
+ if (dest.size() == 1 && dest[0].pos == item->GetPos())
+ {
+ _player->SendEquipError(EQUIP_ERR_CANT_SWAP, item, NULL);
+ continue;
+ }
+
+ // store reagent
+ _player->RemoveItem(item->GetBagSlot(), item->GetSlot(), true);
+ _player->BankItem(dest, item, true);
+ anyDeposited = true;
+ }
+}
+
+void WorldSession::HandleAutoBankReagentOpcode(WorldPackets::Bank::AutoBankReagent& autoBankReagent)
+{
+ if (!CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleAutoBankReagentOpcode - %s not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str());
+ return;
+ }
+
+ if (!_player->IsReagentBankUnlocked())
+ {
+ _player->SendEquipError(EQUIP_ERR_REAGENT_BANK_LOCKED);
+ return;
+ }
+
+ Item* item = _player->GetItemByPos(autoBankReagent.PackSlot, autoBankReagent.Slot);
+ if (!item)
+ return;
+
+ ItemPosCountVec dest;
+ InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, item, false, true, true);
+ if (msg != EQUIP_ERR_OK)
+ {
+ _player->SendEquipError(msg, item, NULL);
+ return;
+ }
+
+ if (dest.size() == 1 && dest[0].pos == item->GetPos())
+ {
+ _player->SendEquipError(EQUIP_ERR_CANT_SWAP, item, NULL);
+ return;
+ }
+
+ _player->RemoveItem(autoBankReagent.PackSlot, autoBankReagent.Slot, true);
+ _player->BankItem(dest, item, true);
+}
+
+void WorldSession::HandleAutoStoreBankReagentOpcode(WorldPackets::Bank::AutoStoreBankReagent& autoStoreBankReagent)
+{
+ if (!CanUseBank())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleAutoBankReagentOpcode - %s not found or you can't interact with him.", m_currentBankerGUID.ToString().c_str());
+ return;
+ }
+
+ if (!_player->IsReagentBankUnlocked())
+ {
+ _player->SendEquipError(EQUIP_ERR_REAGENT_BANK_LOCKED);
+ return;
+ }
+
+ Item* pItem = _player->GetItemByPos(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot);
+ if (!pItem)
+ return;
+
+ if (_player->IsReagentBankPos(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot))
+ {
+ ItemPosCountVec dest;
+ InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false);
+ if (msg != EQUIP_ERR_OK)
+ {
+ _player->SendEquipError(msg, pItem, NULL);
+ return;
+ }
+
+ _player->RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true);
+ _player->StoreItem(dest, pItem, true);
+ }
+ else
+ {
+ ItemPosCountVec dest;
+ InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false, true, true);
+ if (msg != EQUIP_ERR_OK)
+ {
+ _player->SendEquipError(msg, pItem, NULL);
+ return;
+ }
+
+ _player->RemoveItem(autoStoreBankReagent.Slot, autoStoreBankReagent.PackSlot, true);
+ _player->BankItem(dest, pItem, true);
+ }
+}
+
void WorldSession::SendShowBank(ObjectGuid guid)
{
m_currentBankerGUID = guid;
diff --git a/src/server/game/Server/Packets/BankPackets.cpp b/src/server/game/Server/Packets/BankPackets.cpp
index 0e299e6a5d0..63f9300c31d 100644
--- a/src/server/game/Server/Packets/BankPackets.cpp
+++ b/src/server/game/Server/Packets/BankPackets.cpp
@@ -35,3 +35,22 @@ void WorldPackets::Bank::BuyBankSlot::Read()
{
_worldPacket >> Guid;
}
+
+void WorldPackets::Bank::AutoBankReagent::Read()
+{
+ _worldPacket >> Inv;
+ _worldPacket >> PackSlot;
+ _worldPacket >> Slot;
+}
+
+void WorldPackets::Bank::AutoStoreBankReagent::Read()
+{
+ _worldPacket >> Inv;
+ _worldPacket >> Slot;
+ _worldPacket >> PackSlot;
+}
+
+void WorldPackets::Bank::ReagentBank::Read()
+{
+ _worldPacket >> Banker;
+}
diff --git a/src/server/game/Server/Packets/BankPackets.h b/src/server/game/Server/Packets/BankPackets.h
index 4277a33a5eb..f43f672bc95 100644
--- a/src/server/game/Server/Packets/BankPackets.h
+++ b/src/server/game/Server/Packets/BankPackets.h
@@ -59,6 +59,42 @@ namespace WorldPackets
ObjectGuid Guid;
};
+
+ class AutoBankReagent final : public ClientPacket
+ {
+ public:
+ AutoBankReagent(WorldPacket&& packet) : ClientPacket(CMSG_AUTOBANK_REAGENT, std::move(packet)) { }
+
+ void Read() override;
+
+ WorldPackets::Item::InvUpdate Inv;
+ uint8 Slot = 0;
+ uint8 PackSlot = 0;
+ };
+
+ class AutoStoreBankReagent final : public ClientPacket
+ {
+ public:
+ AutoStoreBankReagent(WorldPacket&& packet) : ClientPacket(CMSG_AUTOSTORE_BANK_REAGENT, std::move(packet)) { }
+
+ void Read() override;
+
+ WorldPackets::Item::InvUpdate Inv;
+ uint8 Slot = 0;
+ uint8 PackSlot = 0;
+ };
+
+ // CMSG_BUY_REAGENT_BANK
+ // CMSG_REAGENT_BANK_DEPOSIT
+ class ReagentBank final : public ClientPacket
+ {
+ public:
+ ReagentBank(WorldPacket&& packet) : ClientPacket(std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid Banker;
+ };
}
}
#endif // BankPackets_h__
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 1927ccc5bc2..22b2b2bef06 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -176,9 +176,9 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_AUTH_CONTINUED_SESSION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess);
DEFINE_HANDLER(CMSG_AUTH_SESSION, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_EarlyProccess);
DEFINE_HANDLER(CMSG_AUTOBANK_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAutoBankItemOpcode);
- DEFINE_HANDLER(CMSG_AUTOBANK_REAGENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_AUTOBANK_REAGENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoBankReagentOpcode);
DEFINE_HANDLER(CMSG_AUTOSTORE_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAutoStoreBankItemOpcode);
- DEFINE_HANDLER(CMSG_AUTOSTORE_BANK_REAGENT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_AUTOSTORE_BANK_REAGENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoStoreBankReagentOpcode);
DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAutoEquipItemOpcode);
DEFINE_HANDLER(CMSG_AUTO_EQUIP_ITEM_SLOT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleAutoEquipItemSlotOpcode);
DEFINE_HANDLER(CMSG_AUTO_GUILD_BANK_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleAutoGuildBankItem);
@@ -231,7 +231,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_BUY_BACK_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBuybackItem);
DEFINE_HANDLER(CMSG_BUY_BANK_SLOT, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBuyBankSlotOpcode);
DEFINE_HANDLER(CMSG_BUY_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleBuyItemOpcode);
- DEFINE_HANDLER(CMSG_BUY_REAGENT_BANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_BUY_REAGENT_BANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleBuyReagentBankOpcode);
DEFINE_HANDLER(CMSG_CAGE_BATTLE_PET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCageBattlePet);
DEFINE_HANDLER(CMSG_CALENDAR_ADD_EVENT, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarAddEvent);
DEFINE_HANDLER(CMSG_CALENDAR_COMMUNITY_INVITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCalendarCommunityInvite);
@@ -369,7 +369,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_DELETE_EQUIPMENT_SET, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDeleteEquipmentSet);
DEFINE_HANDLER(CMSG_DEL_FRIEND, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelFriendOpcode);
DEFINE_HANDLER(CMSG_DEL_IGNORE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleDelIgnoreOpcode);
- DEFINE_HANDLER(CMSG_DEPOSIT_REAGENT_BANK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_DEPOSIT_REAGENT_BANK, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReagentBankDepositOpcode);
DEFINE_HANDLER(CMSG_DESTROY_ITEM, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleDestroyItemOpcode);
DEFINE_HANDLER(CMSG_DF_BOOT_PLAYER_VOTE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleLfgSetBootVoteOpcode);
DEFINE_HANDLER(CMSG_DF_CONFIRM_EXPAND_SEARCH, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 1d63ec49e85..dbe867b142a 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -160,6 +160,9 @@ namespace WorldPackets
class AutoBankItem;
class AutoStoreBankItem;
class BuyBankSlot;
+ class AutoBankReagent;
+ class AutoStoreBankReagent;
+ class ReagentBank;
}
namespace Battlefield
@@ -1448,6 +1451,10 @@ class TC_GAME_API WorldSession
void HandleAutoBankItemOpcode(WorldPackets::Bank::AutoBankItem& packet);
void HandleAutoStoreBankItemOpcode(WorldPackets::Bank::AutoStoreBankItem& packet);
void HandleBuyBankSlotOpcode(WorldPackets::Bank::BuyBankSlot& packet);
+ void HandleBuyReagentBankOpcode(WorldPackets::Bank::ReagentBank& reagentBank);
+ void HandleAutoBankReagentOpcode(WorldPackets::Bank::AutoBankReagent& autoBankRegent);
+ void HandleAutoStoreBankReagentOpcode(WorldPackets::Bank::AutoStoreBankReagent& autoStoreBankReagent);
+ void HandleReagentBankDepositOpcode(WorldPackets::Bank::ReagentBank& reagentBank);
// Black Market
void HandleBlackMarketOpen(WorldPackets::BlackMarket::BlackMarketOpen& blackMarketOpen);
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 96d940a3089..2e316c09e26 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -233,6 +233,8 @@ public:
itemPos = "[equipped]";
else if (Player::IsInventoryPos(itemBag, itemSlot))
itemPos = "[in inventory]";
+ else if (Player::IsReagentBankPos(itemBag, itemSlot))
+ itemPos = "[in reagent bank]";
else if (Player::IsBankPos(itemBag, itemSlot))
itemPos = "[in bank]";
else