32#include <boost/dynamic_bitset.hpp>
37 std::vector<uint32> DefaultWarbandScenes;
48 TC_LOG_INFO(
"server.loading",
">> Loaded 0 mount definitions. DB table `mount_definitions` is empty.");
54 Field* fields = result->Fetch();
61 TC_LOG_ERROR(
"sql.sql",
"Mount spell {} defined in `mount_definitions` does not exist in Mount.db2, skipped", spellId);
65 if (otherFactionSpellId && !
sDB2Manager.GetMount(otherFactionSpellId))
67 TC_LOG_ERROR(
"sql.sql",
"otherFactionSpellId {} defined in `mount_definitions` for spell {} does not exist in Mount.db2, skipped", otherFactionSpellId, spellId);
71 FactionSpecificMounts[spellId] = otherFactionSpellId;
72 }
while (result->NextRow());
81 DefaultWarbandScenes.push_back(warbandScene->ID);
101 _transmogIllusions(
std::make_unique<
boost::dynamic_bitset<
uint32>>())
153 Field* fields = result->Fetch();
155 _toys.emplace(itemId, GetToyFlags(fields[1].GetBool(), fields[2].GetBool()));
156 }
while (result->NextRow());
162 for (
auto const& toy :
_toys)
175 return _toys.insert(ToyBoxContainer::value_type(itemId, GetToyFlags(isFavourite, hasFanfare))).second;
180 ToyBoxContainer::iterator itr =
_toys.find(itemId);
181 if (itr ==
_toys.end())
192 auto itr =
_toys.find(itemId);
193 if (itr ==
_toys.end())
214 Field* fields = result->Fetch();
224 for (
int32 upgradeLevel = std::size(heirloom->
UpgradeItemID) - 1; upgradeLevel >= 0; --upgradeLevel)
226 if (
flags & (1 << upgradeLevel))
234 }
while (result->NextRow());
245 stmt->
setUInt32(2, heirloom.second.flags);
257 HeirloomContainer::const_iterator itr =
_heirlooms.find(itemId);
259 return itr->second.bonusId;
290 HeirloomContainer::iterator itr =
_heirlooms.find(itemId);
297 for (
size_t upgradeLevel = 0; upgradeLevel < std::size(heirloom->
UpgradeItemID); ++upgradeLevel)
301 flags |= 1 << upgradeLevel;
307 item->AddBonuses(bonusId);
311 uint32 offset =
uint32(std::ranges::distance(heirlooms.begin(), std::ranges::find(heirlooms,
int32(itemId))));
314 itr->second.flags =
flags;
315 itr->second.bonusId = bonusId;
332 uint32 heirloomItemId = heirloom->StaticUpgradedItemID;
337 newItemId = heirloomDiff->ItemID;
341 heirloomItemId = heirloomSub->ItemID;
351 uint32 offset =
uint32(std::ranges::distance(heirlooms.begin(), std::ranges::find(heirlooms,
int32(itr->first))));
364 for (
uint32 bonusId : bonusListIDs)
366 if (bonusId != itr->second.bonusId)
381 AddMount(m.first, m.second,
false,
false);
391 Field* fields = result->Fetch();
399 }
while (result->NextRow());
404 for (
auto const& mount :
_mounts)
424 MountDefinitionMap::const_iterator itr = FactionSpecificMounts.find(spellId);
425 if (itr != FactionSpecificMounts.end() && !factionMount)
428 _mounts.insert(MountContainer::value_type(spellId,
flags));
447 auto itr =
_mounts.find(spellId);
467 tempMounts.insert(mount);
471 mountUpdate.
Mounts = &tempMounts;
475template <std::invocable<u
int32> OutputAction>
514 if (knownAppearances)
516 std::vector<uint32> blocks;
519 Field* fields = knownAppearances->Fetch();
521 if (blobIndex >= blocks.size())
522 blocks.resize(blobIndex + 1);
524 blocks[blobIndex] = fields[1].
GetUInt32();
526 }
while (knownAppearances->NextRow());
529 boost::from_block_range(blocks.begin(), blocks.end(), *
_appearances);
532 if (favoriteAppearances)
537 }
while (favoriteAppearances->NextRow());
541 static uint32 constexpr hiddenAppearanceItems[] =
555 for (
uint32 hiddenItem : hiddenAppearanceItems)
573 LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_APPEARANCES);
574 stmt->setUInt32(0, _owner->GetBattlenetAccountId());
575 stmt->setUInt16(1, blockIndex);
576 stmt->setUInt32(2, blockValue);
584 for (
auto itr = _favoriteAppearances.begin(); itr != _favoriteAppearances.end();)
590 stmt->
setUInt32(0, _owner->GetBattlenetAccountId());
598 stmt->
setUInt32(0, _owner->GetBattlenetAccountId());
601 itr = _favoriteAppearances.erase(itr);
643 if (!itemModifiedAppearance)
653 if (transmogSetItems.empty())
656 std::array<int8, EQUIPMENT_SLOT_END> knownPieces;
657 knownPieces.fill(-1);
661 if (!itemModifiedAppearance)
669 if (transmogSlot < 0 || knownPieces[transmogSlot] == 1)
672 auto [hasAppearance, isTemporary] =
HasItemAppearance(transmogSetItem->ItemModifiedAppearanceID);
674 knownPieces[transmogSlot] = (hasAppearance && !isTemporary) ? 1 : 0;
682 if (!itemModifiedAppearance)
761 uint32 blockIndex = itemModifiedAppearance->
ID / 32;
762 uint32 bitIndex = itemModifiedAppearance->
ID % 32;
776 if (transmogSlot >= 0)
784 if (
Quest const* quest =
sObjectMgr->GetQuestTemplate(set->TrackingQuestID))
795 if (itemsWithAppearance.empty())
798 itemsWithAppearance.insert(itemGuid);
804 if (!itemModifiedAppearance)
811 itr->second.erase(item->
GetGUID());
812 if (itr->second.empty())
821 if (itemModifiedAppearanceId < _appearances->size() &&
_appearances->test(itemModifiedAppearanceId))
822 return {
true,
false };
825 return {
true,
true };
827 return {
false,
false };
834 return temporaryAppearance->second;
836 return std::unordered_set<ObjectGuid>();
841 std::unordered_set<uint32> appearances;
843 while (
id != boost::dynamic_bitset<uint32>::npos)
905 if (knownTransmogIllusions)
907 std::vector<uint32> blocks;
910 Field* fields = knownTransmogIllusions->Fetch();
912 if (blobIndex >= blocks.size())
913 blocks.resize(blobIndex + 1);
915 blocks[blobIndex] = fields[1].
GetUInt32();
917 }
while (knownTransmogIllusions->NextRow());
924 static uint16 constexpr defaultIllusions[] =
935 for (
uint16 illusionId : defaultIllusions)
952 LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS);
953 stmt->setUInt32(0, _owner->GetBattlenetAccountId());
954 stmt->setUInt16(1, blockIndex);
955 stmt->setUInt32(2, blockValue);
975 uint32 blockIndex = transmogIllusionId / 32;
976 uint32 bitIndex = transmogIllusionId % 32;
993 if (unlockedTransmogOutfits)
997 Field* fields = unlockedTransmogOutfits->Fetch();
1006 }
while (unlockedTransmogOutfits->NextRow());
1019 stmt->
setInt32(1, transmogOutfitId);
1020 trans->Append(stmt);
1044 if (knownWarbandScenes)
1048 Field* fields = knownWarbandScenes->Fetch();
1056 bool isFavorite = fields[1].
GetBool();
1057 bool hasFanfare = fields[2].
GetBool();
1066 }
while (knownWarbandScenes->NextRow());
1069 for (
uint32 warbandSceneId : DefaultWarbandScenes)
1070 if (
auto [itr, isNew] =
_warbandScenes.try_emplace(warbandSceneId); isNew)
1079 auto& [warbandSceneId, data] = *itr;
1088 trans->Append(stmt);
1098 trans->Append(stmt);
1106 trans->Append(stmt);
1124 uint32 blockIndex = warbandSceneId / 32;
1125 uint32 bitIndex = warbandSceneId % 32;
1160 item.
ID = warbandSceneId;
1162 item.
Flags = data.Flags.AsUnderlyingType();
std::map< uint32, MountStatusFlags > MountContainer
std::unordered_map< uint32, uint32 > MountDefinitionMap
WarbandSceneCollectionFlags
DB2Storage< ItemEntry > sItemStore("Item.db2", &ItemLoadInfo::Instance)
DB2Storage< ItemSearchNameEntry > sItemSearchNameStore("ItemSearchName.db2", &ItemSearchNameLoadInfo::Instance)
DB2Storage< TransmogOutfitEntryEntry > sTransmogOutfitEntryStore("TransmogOutfitEntry.db2", &TransmogOutfitEntryLoadInfo::Instance)
DB2Storage< ItemModifiedAppearanceEntry > sItemModifiedAppearanceStore("ItemModifiedAppearance.db2", &ItemModifiedAppearanceLoadInfo::Instance)
DB2Storage< WarbandSceneEntry > sWarbandSceneStore("WarbandScene.db2", &WarbandSceneLoadInfo::Instance)
@ CollectTransmogSetFromGroup
SQLTransaction< LoginDatabaseConnection > LoginDatabaseTransaction
std::shared_ptr< ResultSet > QueryResult
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
DatabaseWorkerPool< WorldDatabaseConnection > WorldDatabase
Accessor to the world database.
@ ITEM_FLAG2_NO_SOURCE_FOR_ITEM_VISUAL
@ ITEM_SUBCLASS_WEAPON_MISCELLANEOUS
@ ITEM_SUBCLASS_WEAPON_SPEAR
@ ITEM_SUBCLASS_WEAPON_EXOTIC2
@ ITEM_SUBCLASS_WEAPON_FISHING_POLE
@ ITEM_SUBCLASS_WEAPON_EXOTIC
@ ITEM_SUBCLASS_WEAPON_THROWN
@ ITEM_SUBCLASS_ARMOR_MISCELLANEOUS
int32 const ItemTransmogrificationSlots[MAX_INVTYPE]
#define TC_LOG_ERROR(filterType__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
@ LOGIN_UPD_BNET_WARBAND_SCENE
@ LOGIN_INS_BNET_TRANSMOG_OUTFITS
@ LOGIN_DEL_BNET_WARBAND_SCENE
@ LOGIN_REP_ACCOUNT_MOUNTS
@ LOGIN_REP_ACCOUNT_HEIRLOOMS
@ LOGIN_INS_BNET_ITEM_FAVORITE_APPEARANCE
@ LOGIN_INS_BNET_WARBAND_SCENE
@ LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE
uint32 GetMSTimeDiffToNow(uint32 oldMSTime)
constexpr std::underlying_type< E >::type AsUnderlyingType(E enumValue)
ObjectGuid const & GetGUID() const
void AddTemporaryAppearance(ObjectGuid const &itemGuid, ItemModifiedAppearanceEntry const *itemModifiedAppearance)
bool UpdateAccountToys(uint32 itemId, bool isFavourite, bool hasFanfare)
void RemoveTemporaryAppearance(Item *item)
void LoadAccountTransmogOutfits(PreparedQueryResult unlockedTransmogOutfits)
void AddItemAppearance(Item *item)
void LoadAccountMounts(PreparedQueryResult result)
void MountSetFavorite(uint32 spellId, bool favorite)
void LoadTransmogOutfits()
void SetWarbandSceneIsFavorite(uint32 warbandSceneId, bool apply)
void SendWarbandSceneCollectionData() const
bool IsSetCompleted(uint32 transmogSetId) const
void SaveAccountToys(LoginDatabaseTransaction trans)
bool UpdateAccountHeirlooms(uint32 itemId, uint32 flags)
void LoadAccountWarbandScenes(PreparedQueryResult knownWarbandScenes)
void ToyClearFanfare(uint32 itemId)
void AddTransmogSet(uint32 transmogSetId)
void OnItemAdded(Item *item)
HeirloomContainer _heirlooms
void SendSingleMountUpdate(std::pair< uint32, MountStatusFlags > mount)
void SaveAccountTransmogIllusions(LoginDatabaseTransaction trans)
void AddTransmogOutfit(int32 transmogOutfitId)
std::unordered_map< uint32, std::unordered_set< ObjectGuid > > _temporaryAppearances
uint32 GetHeirloomBonus(uint32 itemId) const
void SaveAccountMounts(LoginDatabaseTransaction trans)
void ToySetFavorite(uint32 itemId, bool favorite)
bool HasTransmogIllusion(uint32 transmogIllusionId) const
void SaveAccountHeirlooms(LoginDatabaseTransaction trans)
std::unordered_map< uint32, CollectionItemState > _favoriteAppearances
bool AddMount(uint32 spellId, MountStatusFlags flags, bool factionMount=false, bool learned=false)
std::unique_ptr< boost::dynamic_bitset< uint32 > > _appearances
void LoadTransmogIllusions()
std::unordered_set< ObjectGuid > GetItemsProvidingTemporaryAppearance(uint32 itemModifiedAppearanceId) const
void UpgradeHeirloom(uint32 itemId, int32 castItem)
static void LoadWarbandSceneDefinitions()
bool HasWarbandScene(uint32 warbandSceneId) const
void LoadAccountHeirlooms(PreparedQueryResult result)
std::unordered_set< uint32 > GetAppearanceIds() const
std::unique_ptr< boost::dynamic_bitset< uint32 > > _transmogIllusions
void LoadAccountTransmogIllusions(PreparedQueryResult knownTransmogIllusions)
CollectionMgr(WorldSession *owner)
bool AddToy(uint32 itemId, bool isFavourite, bool hasFanfare)
void SaveAccountWarbandScenes(LoginDatabaseTransaction trans)
void AddHeirloom(uint32 itemId, uint32 flags)
void CheckHeirloomUpgrades(Item *item)
void LoadAccountItemAppearances(PreparedQueryResult knownAppearances, PreparedQueryResult favoriteAppearances)
std::pair< bool, bool > HasItemAppearance(uint32 itemModifiedAppearanceId) const
void SaveAccountTransmogOutfits(LoginDatabaseTransaction trans)
bool CanAddAppearance(ItemModifiedAppearanceEntry const *itemModifiedAppearance) const
void AddWarbandScene(uint32 warbandSceneId)
void SetAppearanceIsFavorite(uint32 itemModifiedAppearanceId, bool apply)
static void LoadMountDefinitions()
void SendFavoriteAppearances() const
void SaveAccountItemAppearances(LoginDatabaseTransaction trans)
void AddTransmogIllusion(uint32 transmogIllusionId)
WarbandSceneCollectionContainer _warbandScenes
void LoadAccountToys(PreparedQueryResult result)
void LoadItemAppearances()
Trinity::Containers::FlatSet< int32 > _transmogOutfits
bool HasTransmogOutfit(int32 transmogOutfitId) const
void SaveToDB(LoginDatabaseTransaction trans)
static bool IsPlayerMeetingCondition(Player const *player, uint32 conditionId)
Class used to access individual fields of database query result.
bool GetBool() const noexcept
uint32 GetUInt32() const noexcept
uint16 GetUInt16() const noexcept
int32 GetInt32() const noexcept
void AddBonuses(uint32 bonusListID)
std::vector< int32 > const & GetBonusListIDs() const
bool IsBOPTradeable() const
bool IsRefundable() const
ItemModifiedAppearanceEntry const * GetItemModifiedAppearance() const
void SendDirectMessage(WorldPacket const *data) const
UF::UpdateField< UF::ActivePlayerData, int32(WowCS::EntityFragment::CGObject), TYPEID_ACTIVE_PLAYER > m_activePlayerData
Item * GetItemByEntry(uint32 entry, ItemSearchLocation where=ItemSearchLocation::Default) const
void AddTransmogFlag(uint32 slot, uint32 flag)
void LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill=0, bool suppressMessaging=false, Optional< PlayerSpellTrait > trait={})
void UpdateCriteria(CriteriaType type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, WorldObject *ref=nullptr)
void AddConditionalTransmog(uint32 itemModifiedAppearanceId)
void AddUnlockedTransmogOutfit(int32 transmogOutfitIds)
void AddIllusionBlock(uint32 blockValue)
void RemoveConditionalTransmog(uint32 itemModifiedAppearanceId)
void AddIllusionFlag(uint32 slot, uint32 flag)
void AddWarbandScenesFlag(uint32 slot, uint32 flag)
void SetHeirloom(uint32 slot, int32 itemId)
void AddUnlockedTransmogOutfits(std::span< int32 const > transmogOutfitIds)
bool HasSpell(uint32 spell) const override
void AddToy(int32 itemId, uint32 flags)
std::vector< Item * > GetItemListByEntry(uint32 entry, bool inBankAlso=false) const
void AddHeirloom(int32 itemId, uint32 flags)
void RewardQuest(Quest const *quest, LootItemType rewardType, uint32 rewardId, Object *questGiver, bool announce=true)
void AddTransmogBlock(uint32 blockValue)
void SetHeirloomFlags(uint32 slot, uint32 flags)
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setInt32(uint8 index, int32 value)
void setUInt8(uint8 index, uint8 value)
bool contains(Key const &value) const
std::pair< iterator, bool > insert(Key const &key)
std::vector< ItemCollectionItemData > Items
WorldPacket const * Write() override
MountContainer const * Mounts
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< uint32 > FavoriteAppearances
Player session in the World.
Player * GetPlayer() const
void SendPacket(WorldPacket const *packet, bool forced=false)
Send a packet to the client.
uint32 GetBattlenetAccountId() const
std::span< TransmogSetItemEntry const *const > GetTransmogSetItems(uint32 transmogSetId)
ItemModifiedAppearanceEntry const * GetDefaultItemModifiedAppearance(uint32 itemId)
std::span< TransmogSetEntry const *const > GetTransmogSetsForItemModifiedAppearance(uint32 itemModifiedAppearanceId)
ItemModifiedAppearanceEntry const * GetItemModifiedAppearance(uint32 itemId, uint32 appearanceModId)
std::span< TransmogOutfitEntryEntry const *const > GetAutomaticallyUnlockedOutfits()
auto MapGetValuePtr(M &map, typename M::key_type const &key)
struct advstd::ranges::Contains contains
OutputAction const * _action
DynamicBitsetBlockOutputIterator & operator++()
DynamicBitsetBlockOutputIterator(OutputAction const &action)
DynamicBitsetBlockOutputIterator & operator=(uint32 value)
DynamicBitsetBlockOutputIterator & operator*()
std::output_iterator_tag iterator_category
DynamicBitsetBlockOutputIterator operator++(int)
std::array< uint16, 6 > UpgradeItemBonusListID
std::array< int32, 6 > UpgradeItemID
uint8 TransmogSourceTypeEnum
uint32 GetQuality() const
InventoryType GetInventoryType() const
bool HasFlag(ItemFlags flag) const
uint32 GetSubClass() const
CollectionItemState State
EnumFlag< WarbandSceneCollectionFlags > Flags