30#include <unordered_map>
34 std::unordered_map<uint64, StoredLootContainer> _lootItemStore;
38FFA(lootItem.freeforall), Blocked(lootItem.is_blocked), Counted(lootItem.is_counted), UnderThreshold(lootItem.is_underthreshold),
39NeedsQuest(lootItem.needs_quest), RandomBonusListId(lootItem.randomBonusListId), Context(lootItem.context), BonusListIDs(lootItem.BonusListIDs)
51 static std::shared_mutex _lock;
58 _lootItemStore.clear();
68 Field* fields = result->Fetch();
86 for (std::string_view bonusList :
Trinity::Tokenize(fields[13].GetStringView(),
' ',
false))
93 }
while (result->NextRow());
98 TC_LOG_INFO(
"server.loading",
">> Loaded 0 stored item loots");
107 Field* fields = result->Fetch();
111 storedContainer.
AddMoney(fields[1].GetUInt32(), trans);
114 }
while (result->NextRow());
119 TC_LOG_INFO(
"server.loading",
">> Loaded 0 stored item money");
128 std::shared_lock lock(*
GetLock());
131 if (itr == _lootItemStore.end())
134 container = &itr->second;
143 for (
auto const& storedItemPair : container->
GetLootItems())
146 li.
itemid = storedItemPair.first;
147 li.
count = storedItemPair.second.Count;
148 li.
LootListId = storedItemPair.second.ItemIndex;
151 li.
is_blocked = storedItemPair.second.Blocked;
152 li.
is_counted = storedItemPair.second.Counted;
156 li.
context = storedItemPair.second.Context;
160 lt->CopyConditions(&li);
167 loot->
items.push_back(li);
174 if (!loot->
items.empty())
176 std::sort(loot->
items.begin(), loot->
items.end(), [](
LootItem const& left,
LootItem const& right) { return left.LootListId < right.LootListId; });
180 while (loot->
items.size() <= loot->
items.back().LootListId)
182 if (loot->
items[lootListId].LootListId != lootListId)
184 auto li = loot->
items.emplace(loot->
items.begin() + lootListId);
185 li->LootListId = lootListId;
186 li->is_looted =
true;
202 std::scoped_lock lock(*
GetLock());
204 auto itr = _lootItemStore.find(containerId);
205 if (itr == _lootItemStore.end())
208 itr->second.RemoveMoney();
215 std::scoped_lock lock(*
GetLock());
216 _lootItemStore.erase(containerId);
234 std::scoped_lock lock(*
GetLock());
236 auto itr = _lootItemStore.find(containerId);
237 if (itr == _lootItemStore.end())
240 itr->second.RemoveItem(type, itemId, count, itemIndex);
251 std::shared_lock lock(*
GetLock());
253 auto itr = _lootItemStore.find(containerId);
254 if (itr != _lootItemStore.end())
256 TC_LOG_ERROR(
"misc",
"Trying to store item loot by player: {} for container id: {} that is already in storage!", player->
GetGUID().
ToString(), containerId);
278 if (!li.AllowedForPlayer(player, loot))
293 std::scoped_lock lock(*
GetLock());
294 _lootItemStore.emplace(containerId, std::move(container));
300 _lootItems.emplace(std::piecewise_construct, std::forward_as_tuple(lootItem.
itemid), std::forward_as_tuple(lootItem));
320 std::ostringstream bonusListIDs;
322 bonusListIDs << bonusListID <<
' ';
355 for (
auto itr = bounds.first; itr != bounds.second; ++itr)
357 if (itr->second.ItemIndex == itemIndex)
@ CHAR_DEL_ITEMCONTAINER_MONEY
@ CHAR_DEL_ITEMCONTAINER_ITEM
@ CHAR_DEL_ITEMCONTAINER_ITEMS
@ CHAR_SEL_ITEMCONTAINER_ITEMS
@ CHAR_INS_ITEMCONTAINER_ITEMS
@ CHAR_INS_ITEMCONTAINER_MONEY
@ CHAR_SEL_ITEMCONTAINER_MONEY
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
LootStore LootTemplates_Item("item_loot_template", "item entry", true)
std::optional< T > Optional
Optional helper class to wrap optional values within.
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
ObjectGuid const & GetGUID() const
Class used to access individual fields of database query result.
uint64 GetUInt64() const noexcept
bool GetBool() const noexcept
uint32 GetUInt32() const noexcept
int8 GetInt8() const noexcept
std::unique_ptr< Loot > m_loot
static LootItemStorage * instance()
void RemoveStoredMoneyForContainer(uint64 containerId)
void AddNewStoredLoot(uint64 containerId, Loot *loot, Player *player)
static std::shared_mutex * GetLock()
void RemoveStoredLootItemForContainer(uint64 containerId, LootItemType type, uint32 itemId, uint32 count, uint32 itemIndex)
bool LoadStoredLoot(Item *item, Player *player)
void RemoveStoredLootForContainer(uint64 containerId)
LootTemplate const * GetLootFor(uint32 loot_id) const
LowType GetCounter() const
std::string ToString() const
void setInt8(uint8 index, int8 value)
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setUInt64(uint8 index, uint64 value)
void setInt32(uint8 index, int32 value)
void setUInt8(uint8 index, uint8 value)
void AddLootItem(LootItem const &lootItem, CharacterDatabaseTransaction trans)
StoredLootItemContainer _lootItems
uint64 const _containerId
void AddMoney(uint32 money, CharacterDatabaseTransaction trans)
void RemoveItem(LootItemType type, uint32 itemId, uint32 count, uint32 itemIndex)
StoredLootItemContainer const & GetLootItems() const
TC_COMMON_API std::vector< std::string_view > Tokenize(std::string_view str, char sep, bool keepEmpty)
bool IsCurrencyToken() const
std::vector< int32 > BonusListIDs
void AddAllowedLooter(Player const *player)
ItemRandomBonusListId randomBonusListId
std::vector< LootItem > items
StoredLootItem(LootItem const &lootItem)