TrinityCore
Bag.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 "Common.h"
19#include "ObjectMgr.h"
20#include "DatabaseEnv.h"
21
22#include "Bag.h"
23#include "Log.h"
24#include "UpdateData.h"
25#include "Player.h"
26#include <sstream>
27
29{
32
33 memset(m_bagslot, 0, sizeof(Item*) * MAX_BAG_SIZE);
34}
35
37{
38 for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
39 if (Item* item = m_bagslot[i])
40 {
41 if (item->IsInWorld())
42 {
43 TC_LOG_FATAL("entities.player.items", "Item {} (slot {}, bag slot {}) in bag {} (slot {}, bag slot {}, m_bagslot {}) is to be deleted but is still in world.",
44 item->GetEntry(), (uint32)item->GetSlot(), (uint32)item->GetBagSlot(),
46 item->RemoveFromWorld();
47 }
48 delete m_bagslot[i];
49 }
50}
51
53{
55
56 for (uint32 i = 0; i < GetBagSize(); ++i)
57 if (m_bagslot[i])
59}
60
62{
63 for (uint32 i = 0; i < GetBagSize(); ++i)
64 if (m_bagslot[i])
66
68}
69
70bool Bag::Create(ObjectGuid::LowType guidlow, uint32 itemid, ItemContext context, Player const* owner)
71{
72 ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(itemid);
73
74 if (!itemProto || itemProto->GetContainerSlots() > MAX_BAG_SIZE)
75 return false;
76
77 Object::_Create(ObjectGuid::Create<HighGuid::Item>(guidlow));
78
79 _bonusData.Initialize(itemProto);
80
81 SetEntry(itemid);
82 SetObjectScale(1.0f);
83
84 if (owner)
85 {
86 SetOwnerGUID(owner->GetGUID());
87 SetContainedIn(owner->GetGUID());
88 }
89
91 SetDurability(itemProto->MaxDurability);
92 SetCount(1);
93 SetContext(context);
94
95 // Setting the number of Slots the Container has
96 SetBagSize(itemProto->GetContainerSlots());
97
98 // Cleaning 20 slots
99 for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
100 {
102 m_bagslot[i] = nullptr;
103 }
104
105 return true;
106}
107
109{
110 Item::SaveToDB(trans);
111}
112
113bool Bag::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fields, uint32 entry)
114{
115 if (!Item::LoadFromDB(guid, owner_guid, fields, entry))
116 return false;
117
118 ItemTemplate const* itemProto = GetTemplate(); // checked in Item::LoadFromDB
119 SetBagSize(itemProto->GetContainerSlots());
120 // cleanup bag content related item value fields (its will be filled correctly from `character_inventory`)
121 for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
122 {
124 delete m_bagslot[i];
125 m_bagslot[i] = nullptr;
126 }
127
128 return true;
129}
130
132{
133 for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
134 if (m_bagslot[i])
135 m_bagslot[i]->DeleteFromDB(trans);
136
137 Item::DeleteFromDB(trans);
138}
139
141{
142 uint32 slots = 0;
143 for (uint32 i=0; i < GetBagSize(); ++i)
144 if (!m_bagslot[i])
145 ++slots;
146
147 return slots;
148}
149
150void Bag::RemoveItem(uint8 slot, bool /*update*/)
151{
152 ASSERT(slot < MAX_BAG_SIZE);
153
154 if (m_bagslot[slot])
155 m_bagslot[slot]->SetContainer(nullptr);
156
157 m_bagslot[slot] = nullptr;
159}
160
161void Bag::StoreItem(uint8 slot, Item* pItem, bool /*update*/)
162{
163 ASSERT(slot < MAX_BAG_SIZE);
164
165 if (pItem && pItem->GetGUID() != GetGUID())
166 {
167 m_bagslot[slot] = pItem;
168 SetSlot(slot, pItem->GetGUID());
169 pItem->SetContainedIn(GetGUID());
170 pItem->SetOwnerGUID(GetOwnerGUID());
171 pItem->SetContainer(this);
172 pItem->SetSlot(slot);
173 }
174}
175
177{
179
180 for (uint32 i = 0; i < GetBagSize(); ++i)
181 if (m_bagslot[i])
183}
184
185void Bag::BuildValuesCreate(ByteBuffer* data, Player const* target) const
186{
188 std::size_t sizePos = data->wpos();
189 *data << uint32(0);
190 *data << uint8(flags);
191 m_objectData->WriteCreate(*data, flags, this, target);
192 m_itemData->WriteCreate(*data, flags, this, target);
193 m_containerData->WriteCreate(*data, flags, this, target);
194 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
195}
196
197void Bag::BuildValuesUpdate(ByteBuffer* data, Player const* target) const
198{
200 std::size_t sizePos = data->wpos();
201 *data << uint32(0);
203
205 m_objectData->WriteUpdate(*data, flags, this, target);
206
208 m_itemData->WriteUpdate(*data, flags, this, target);
209
211 m_containerData->WriteUpdate(*data, flags, this, target);
212
213 data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
214}
215
217 UF::ItemData::Mask const& requestedItemMask, UF::ContainerData::Mask const& requestedContainerMask, Player const* target) const
218{
221 if (requestedObjectMask.IsAnySet())
222 valuesMask.Set(TYPEID_OBJECT);
223
224 UF::ItemData::Mask itemMask = requestedItemMask;
225 m_itemData->FilterDisallowedFieldsMaskForFlag(itemMask, flags);
226 if (itemMask.IsAnySet())
227 valuesMask.Set(TYPEID_ITEM);
228
229 if (requestedContainerMask.IsAnySet())
230 valuesMask.Set(TYPEID_CONTAINER);
231
233 std::size_t sizePos = buffer.wpos();
234 buffer << uint32(0);
235 buffer << uint32(valuesMask.GetBlock(0));
236
237 if (valuesMask[TYPEID_OBJECT])
238 m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
239
240 if (valuesMask[TYPEID_ITEM])
241 m_itemData->WriteUpdate(buffer, itemMask, true, this, target);
242
243 if (valuesMask[TYPEID_CONTAINER])
244 m_containerData->WriteUpdate(buffer, requestedContainerMask, true, this, target);
245
246 buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
247
248 data->AddUpdateBlock();
249}
250
252{
253 UpdateData udata(player->GetMapId());
254 WorldPacket packet;
255
257
258 udata.BuildPacket(&packet);
259 player->SendDirectMessage(&packet);
260}
261
262void Bag::ClearUpdateMask(bool remove)
263{
265 Item::ClearUpdateMask(remove);
266}
267
268// If the bag is empty returns true
269bool Bag::IsEmpty() const
270{
271 for (uint32 i = 0; i < GetBagSize(); ++i)
272 if (m_bagslot[i])
273 return false;
274
275 return true;
276}
277
279{
280 for (uint32 i = 0; i < GetBagSize(); ++i)
281 if (m_bagslot[i] != nullptr)
282 if (m_bagslot[i]->GetGUID() == guid)
283 return i;
284
285 return NULL_SLOT;
286}
287
289{
290 if (slot < GetBagSize())
291 return m_bagslot[slot];
292
293 return nullptr;
294}
295
296std::string Bag::GetDebugInfo() const
297{
298 std::stringstream sstr;
299 sstr << Item::GetDebugInfo();
300 return sstr.str();
301}
302
304{
305 return bag->GetBagSize();
306}
307
308Item* GetItemInBag(Bag const* bag, uint8 slot)
309{
310 return bag->GetItemByPos(slot);
311}
Item * GetItemInBag(Bag const *bag, uint8 slot)
Definition: Bag.cpp:308
#define MAX_BAG_SIZE
Definition: Bag.h:22
ItemContext
Definition: DBCEnums.h:1063
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
uint16 flags
Definition: DisableMgr.cpp:49
#define ASSERT
Definition: Errors.h:68
#define TC_LOG_FATAL(filterType__,...)
Definition: Log.h:168
@ TYPEID_OBJECT
Definition: ObjectGuid.h:35
@ TYPEID_ITEM
Definition: ObjectGuid.h:36
@ TYPEID_CONTAINER
Definition: ObjectGuid.h:37
@ TYPEMASK_CONTAINER
Definition: ObjectGuid.h:57
#define sObjectMgr
Definition: ObjectMgr.h:1946
@ NULL_SLOT
Definition: Unit.h:63
Definition: Bag.h:27
uint32 GetBagSize() const
Definition: Bag.h:45
void AddToWorld() override
Definition: Bag.cpp:52
void StoreItem(uint8 slot, Item *pItem, bool update)
Definition: Bag.cpp:161
void RemoveFromWorld() override
Definition: Bag.cpp:61
bool IsEmpty() const
Definition: Bag.cpp:269
UF::UpdateField< UF::ContainerData, 0, TYPEID_CONTAINER > m_containerData
Definition: Bag.h:79
void SaveToDB(CharacterDatabaseTransaction trans) override
Definition: Bag.cpp:108
void BuildValuesUpdate(ByteBuffer *data, Player const *target) const override
Definition: Bag.cpp:197
void ClearUpdateMask(bool remove) override
Definition: Bag.cpp:262
void BuildValuesUpdateForPlayerWithMask(UpdateData *data, UF::ObjectData::Mask const &requestedObjectMask, UF::ItemData::Mask const &requestedItemMask, UF::ContainerData::Mask const &requestedContainerMask, Player const *target) const
Definition: Bag.cpp:216
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const override
Definition: Bag.cpp:176
void SetSlot(uint32 slot, ObjectGuid guid)
Definition: Bag.h:83
~Bag()
Definition: Bag.cpp:36
void SetBagSize(uint32 numSlots)
Definition: Bag.h:82
Item * GetItemByPos(uint8 slot) const
Definition: Bag.cpp:288
std::string GetDebugInfo() const override
Definition: Bag.cpp:296
void RemoveItem(uint8 slot, bool update)
Definition: Bag.cpp:150
void DeleteFromDB(CharacterDatabaseTransaction trans) override
Definition: Bag.cpp:131
bool Create(ObjectGuid::LowType guidlow, uint32 itemid, ItemContext context, Player const *owner) override
Definition: Bag.cpp:70
Item * m_bagslot[MAX_BAG_SIZE]
Definition: Bag.h:86
uint32 GetFreeSlots() const
Definition: Bag.cpp:140
uint8 GetSlotByItemGUID(ObjectGuid guid) const
Definition: Bag.cpp:278
Bag()
Definition: Bag.cpp:28
bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field *fields, uint32 entry) override
Definition: Bag.cpp:113
void BuildValuesCreate(ByteBuffer *data, Player const *target) const override
Definition: Bag.cpp:185
size_t wpos() const
Definition: ByteBuffer.h:412
void put(std::size_t pos, T value)
Definition: ByteBuffer.h:220
Class used to access individual fields of database query result.
Definition: Field.h:90
Definition: Item.h:170
std::string GetDebugInfo() const override
Definition: Item.cpp:2819
uint8 GetSlot() const
Definition: Item.h:280
virtual void SaveToDB(CharacterDatabaseTransaction trans)
Definition: Item.cpp:561
void SetContext(ItemContext context)
Definition: Item.h:442
void SetCount(uint32 value)
Definition: Item.cpp:1275
void SetDurability(uint32 durability)
Definition: Item.h:258
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:1141
void ClearUpdateMask(bool remove) override
Definition: Item.cpp:1791
ObjectGuid GetOwnerGUID() const
Definition: Item.h:188
BonusData _bonusData
Definition: Item.h:452
void SetContainedIn(ObjectGuid guid)
Definition: Item.h:191
void SetSlot(uint8 slot)
Definition: Item.h:283
virtual bool LoadFromDB(ObjectGuid::LowType guid, ObjectGuid ownerGuid, Field *fields, uint32 entry)
Definition: Item.cpp:828
void SetOwnerGUID(ObjectGuid guid)
Definition: Item.h:189
void SetContainer(Bag *container)
Definition: Item.h:285
uint8 GetBagSlot() const
Definition: Item.cpp:1239
UF::UpdateFieldFlag GetUpdateFieldFlagsFor(Player const *target) const override
Definition: Item.cpp:1700
static void DeleteFromDB(CharacterDatabaseTransaction trans, ObjectGuid::LowType itemGuid)
Definition: Item.cpp:1088
UF::UpdateField< UF::ItemData, 0, TYPEID_ITEM > m_itemData
Definition: Item.h:449
static ObjectGuid const Empty
Definition: ObjectGuid.h:274
uint64 LowType
Definition: ObjectGuid.h:278
uint16 m_objectType
Definition: Object.h:401
ObjectGuid const & GetGUID() const
Definition: Object.h:160
UF::UpdateField< UF::ObjectData, 0, TYPEID_OBJECT > m_objectData
Definition: Object.h:267
virtual void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition: Object.cpp:137
void SetUpdateFieldValue(UF::UpdateFieldSetter< T > setter, typename UF::UpdateFieldSetter< T >::value_type value)
Definition: Object.h:287
uint32 GetEntry() const
Definition: Object.h:161
UF::UpdateFieldHolder m_values
Definition: Object.h:266
void _Create(ObjectGuid const &guid)
Definition: Object.cpp:101
ByteBuffer & PrepareValuesUpdateBuffer(UpdateData *data) const
Definition: Object.cpp:225
virtual void AddToWorld()
Definition: Object.cpp:107
virtual void RemoveFromWorld()
Definition: Object.cpp:124
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void SetEntry(uint32 entry)
Definition: Object.h:162
virtual void SetObjectScale(float scale)
Definition: Object.h:165
TypeID m_objectTypeId
Definition: Object.h:403
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6324
Mask const & GetChangesMask() const
Definition: UpdateField.h:605
MutableFieldReference< T, false > ModifyValue(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:683
void ClearChangesMask(UpdateField< T, BlockBit, Bit >(Derived::*field))
Definition: UpdateField.h:690
bool HasChanged(uint32 index) const
Definition: UpdateField.h:701
uint32 GetChangedObjectTypeMask() const
Definition: UpdateField.h:696
bool BuildPacket(WorldPacket *packet)
Definition: UpdateData.cpp:40
void AddUpdateBlock()
Definition: UpdateData.h:49
uint32 GetBlock(uint32 index) const
Definition: UpdateMask.h:53
void Set(uint32 index)
Definition: UpdateMask.h:84
constexpr uint32 GetMapId() const
Definition: Position.h:201
UpdateFieldFlag
Definition: UpdateField.h:34
UF::ObjectData::Base ObjectMask
Definition: Bag.h:70
void operator()(Player const *player) const
Definition: Bag.cpp:251
UF::ContainerData::Base ContainerMask
Definition: Bag.h:72
UF::ItemData::Base ItemMask
Definition: Bag.h:71
void Initialize(ItemTemplate const *proto)
Definition: Item.cpp:2829
uint32 GetContainerSlots() const
Definition: ItemTemplate.h:797
uint32 MaxDurability
Definition: ItemTemplate.h:827
UpdateField< uint32, 0, 11 > MaxDurability
Definition: UpdateFields.h:130