diff options
author | MitchesD <majklprofik@seznam.cz> | 2016-10-01 13:48:16 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2016-10-01 13:48:16 +0200 |
commit | ad3da9c971640c4ecc00cf4794ccc08057da7d38 (patch) | |
tree | dd17307ceb82d116f37e1aea5443e3c4e0914f19 /src | |
parent | 20f0db0e470342f6d599818f207ce1a6d9dcbadc (diff) |
Core/Player: Implemented account wide mounts
Closes #17369
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.cpp | 154 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.h | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Handlers/MiscHandler.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MiscPackets.cpp | 22 | ||||
-rw-r--r-- | src/server/game/Server/Packets/MiscPackets.h | 22 | ||||
-rw-r--r-- | src/server/game/Server/Protocol/Opcodes.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 3 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 |
12 files changed, 249 insertions, 8 deletions
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index d1491aef171..083bdb383f1 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -163,6 +163,10 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_ACCOUNT_HEIRLOOMS, "SELECT itemId, flags FROM battlenet_account_heirlooms WHERE accountId = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_REP_ACCOUNT_HEIRLOOMS, "REPLACE INTO battlenet_account_heirlooms (accountId, itemId, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC); + // Account wide mounts + PrepareStatement(LOGIN_SEL_ACCOUNT_MOUNTS, "SELECT mountSpellId, flags FROM battlenet_account_mounts WHERE battlenetAccountId = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_REP_ACCOUNT_MOUNTS, "REPLACE INTO battlenet_account_mounts (battlenetAccountId, mountSpellId, flags) VALUES (?, ?, ?)", CONNECTION_ASYNC); + // Transmog collection PrepareStatement(LOGIN_SEL_BNET_ITEM_APPEARANCES, "SELECT blobIndex, appearanceMask FROM battlenet_item_appearances WHERE battlenetAccountId = ? ORDER BY blobIndex DESC", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_BNET_ITEM_APPEARANCES, "INSERT INTO battlenet_item_appearances (battlenetAccountId, blobIndex, appearanceMask) VALUES (?, ?, ?) " diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index ecb2cb6786f..bddb119544e 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -152,6 +152,9 @@ enum LoginDatabaseStatements LOGIN_SEL_ACCOUNT_HEIRLOOMS, LOGIN_REP_ACCOUNT_HEIRLOOMS, + LOGIN_SEL_ACCOUNT_MOUNTS, + LOGIN_REP_ACCOUNT_MOUNTS, + LOGIN_SEL_BNET_ITEM_APPEARANCES, LOGIN_INS_BNET_ITEM_APPEARANCES, LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES, diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp index 297c67e3acf..b8b438ab64f 100644 --- a/src/server/game/Entities/Player/CollectionMgr.cpp +++ b/src/server/game/Entities/Player/CollectionMgr.cpp @@ -16,10 +16,53 @@ */ #include "CollectionMgr.h" +#include "MiscPackets.h" #include "ObjectMgr.h" #include "Player.h" #include "TransmogrificationPackets.h" +namespace +{ + MountDefinitionMap FactionSpecificMounts; +} + +void CollectionMgr::LoadMountDefinitions() +{ + uint32 oldMSTime = getMSTime(); + + QueryResult result = WorldDatabase.Query("SELECT spellId, otherFactionSpellId FROM mount_definitions"); + + if (!result) + { + TC_LOG_INFO("server.loading", ">> Loaded 0 mount definitions. DB table `mount_definitions` is empty."); + return; + } + + do + { + Field* fields = result->Fetch(); + + uint32 spellId = fields[0].GetUInt32(); + uint32 otherFactionSpellId = fields[1].GetUInt32(); + + if (!sDB2Manager.GetMount(spellId)) + { + TC_LOG_ERROR("sql.sql", "Mount spell %u defined in `mount_definitions` does not exist in Mount.db2, skipped", spellId); + continue; + } + + if (otherFactionSpellId && !sDB2Manager.GetMount(otherFactionSpellId)) + { + TC_LOG_ERROR("sql.sql", "otherFactionSpellId %u defined in `mount_definitions` for spell %u does not exist in Mount.db2, skipped", otherFactionSpellId, spellId); + continue; + } + + FactionSpecificMounts[spellId] = otherFactionSpellId; + } while (result->NextRow()); + + TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " mount definitions in %u ms", FactionSpecificMounts.size(), GetMSTimeDiffToNow(oldMSTime)); +} + CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner), _appearances() { } @@ -195,7 +238,7 @@ void CollectionMgr::UpgradeHeirloom(uint32 itemId, uint32 castItem) // Get heirloom offset to update only one part of dynamic field std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS); - uint8 offset = std::find(fields.begin(), fields.end(), itemId) - fields.begin(); + uint8 offset = uint8(std::find(fields.begin(), fields.end(), itemId) - fields.begin()); player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, flags); itr->second.flags = flags; @@ -235,7 +278,7 @@ void CollectionMgr::CheckHeirloomUpgrades(Item* item) if (newItemId) { std::vector<uint32> const& fields = player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_HEIRLOOMS); - uint8 offset = std::find(fields.begin(), fields.end(), itr->first) - fields.begin(); + uint8 offset = uint8(std::find(fields.begin(), fields.end(), itr->first) - fields.begin()); player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOMS, offset, newItemId); player->SetDynamicValue(PLAYER_DYNAMIC_FIELD_HEIRLOOM_FLAGS, offset, 0); @@ -274,6 +317,107 @@ bool CollectionMgr::CanApplyHeirloomXpBonus(uint32 itemId, uint32 level) return level <= 60; } +void CollectionMgr::LoadMounts() +{ + for (auto const& m : _mounts) + AddMount(m.first, m.second, false, false); +} + +void CollectionMgr::LoadAccountMounts(PreparedQueryResult result) +{ + if (!result) + return; + + do + { + Field* fields = result->Fetch(); + uint32 mountSpellId = fields[0].GetUInt32(); + MountStatusFlags flags = MountStatusFlags(fields[1].GetUInt8()); + + if (!sDB2Manager.GetMount(mountSpellId)) + continue; + + _mounts[mountSpellId] = flags; + } while (result->NextRow()); +} + +void CollectionMgr::SaveAccountMounts(SQLTransaction& trans) +{ + for (auto const& mount : _mounts) + { + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_MOUNTS); + stmt->setUInt32(0, _owner->GetBattlenetAccountId()); + stmt->setUInt32(1, mount.first); + stmt->setUInt8(2, mount.second); + trans->Append(stmt); + } +} + +bool CollectionMgr::AddMount(uint32 spellId, MountStatusFlags flags, bool factionMount /*= false*/, bool learned /*= false*/) +{ + Player* player = _owner->GetPlayer(); + if (!player) + return false; + + MountEntry const* mount = sDB2Manager.GetMount(spellId); + if (!mount) + return false; + + MountDefinitionMap::const_iterator itr = FactionSpecificMounts.find(spellId); + if (itr != FactionSpecificMounts.end() && !factionMount) + AddMount(itr->second, flags, true, learned); + + _mounts.insert(MountContainer::value_type(spellId, flags)); + + // Mount condition only applies to using it, should still learn it. + if (mount->PlayerConditionId) + { + PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(mount->PlayerConditionId); + if (!ConditionMgr::IsPlayerMeetingCondition(player, playerCondition)) + return false; + } + + if (!learned) + { + if (!factionMount) + SendSingleMountUpdate(std::make_pair(spellId, flags)); + if (!player->HasSpell(spellId)) + player->LearnSpell(spellId, true); + } + + return true; +} + +void CollectionMgr::MountSetFavorite(uint32 spellId, bool favorite) +{ + auto itr = _mounts.find(spellId); + if (itr == _mounts.end()) + return; + + if (favorite) + itr->second = MountStatusFlags(itr->second | MOUNT_IS_FAVORITE); + else + itr->second = MountStatusFlags(itr->second & ~MOUNT_IS_FAVORITE); + + SendSingleMountUpdate(*itr); +} + +void CollectionMgr::SendSingleMountUpdate(std::pair<uint32, MountStatusFlags> mount) +{ + Player* player = _owner->GetPlayer(); + if (!player) + return; + + // Temporary container, just need to store only selected mount + MountContainer tempMounts; + tempMounts.insert(mount); + + WorldPackets::Misc::AccountMountUpdate mountUpdate; + mountUpdate.IsFullUpdate = false; + mountUpdate.Mounts = &tempMounts; + player->SendDirectMessage(mountUpdate.Write()); +} + struct DynamicBitsetBlockOutputIterator : public std::iterator<std::output_iterator_tag, void, void, void, void> { explicit DynamicBitsetBlockOutputIterator(std::function<void(uint32)>&& action) : _action(std::forward<std::function<void(uint32)>>(action)) { } @@ -351,7 +495,7 @@ void CollectionMgr::SaveAccountItemAppearances(SQLTransaction& trans) if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ITEM_APPEARANCES); - stmt->setUInt32(0, GetOwner()->GetBattlenetAccountId()); + stmt->setUInt32(0, _owner->GetBattlenetAccountId()); stmt->setUInt16(1, blockIndex); stmt->setUInt32(2, blockValue); trans->Append(stmt); @@ -515,7 +659,7 @@ void CollectionMgr::AddItemAppearance(ItemModifiedAppearanceEntry const* itemMod { if (_appearances.size() <= itemModifiedAppearance->ID) { - uint32 numBlocks = _appearances.num_blocks(); + std::size_t numBlocks = _appearances.num_blocks(); _appearances.resize(itemModifiedAppearance->ID + 1); numBlocks = _appearances.num_blocks() - numBlocks; while (numBlocks--) @@ -619,7 +763,7 @@ void CollectionMgr::SendFavoriteAppearances() const transmogCollectionUpdate.FavoriteAppearances.reserve(_favoriteAppearances.size()); for (auto itr = _favoriteAppearances.begin(); itr != _favoriteAppearances.end(); ++itr) if (itr->second != FavoriteAppearanceState::Removed) - transmogCollectionUpdate.FavoriteAppearances.push_back(itr->first); + transmogCollectionUpdate.FavoriteAppearances.push_back(itr->first); _owner->SendPacket(transmogCollectionUpdate.Write()); } diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h index 7090995689d..f78a88950ba 100644 --- a/src/server/game/Entities/Player/CollectionMgr.h +++ b/src/server/game/Entities/Player/CollectionMgr.h @@ -48,12 +48,22 @@ struct HeirloomData typedef std::map<uint32, bool> ToyBoxContainer; typedef std::map<uint32, HeirloomData> HeirloomContainer; +enum MountStatusFlags : uint8 +{ + MOUNT_STATUS_NONE = 0x00, + MOUNT_NEEDS_FANFARE = 0x01, + MOUNT_IS_FAVORITE = 0x02 +}; + +typedef std::map<uint32, MountStatusFlags> MountContainer; +typedef std::unordered_map<uint32, uint32> MountDefinitionMap; + class TC_GAME_API CollectionMgr { public: explicit CollectionMgr(WorldSession* owner); - WorldSession* GetOwner() const { return _owner; } + static void LoadMountDefinitions(); // Account-wide toys void LoadToys(); @@ -83,6 +93,13 @@ public: HeirloomContainer const& GetAccountHeirlooms() const { return _heirlooms; } // Account-wide mounts + void LoadMounts(); + void LoadAccountMounts(PreparedQueryResult result); + void SaveAccountMounts(SQLTransaction& trans); + bool AddMount(uint32 spellId, MountStatusFlags flags, bool factionMount = false, bool learned = false); + void MountSetFavorite(uint32 spellId, bool favorite); + void SendSingleMountUpdate(std::pair<uint32, MountStatusFlags> mount); + MountContainer const& GetAccountMounts() const { return _mounts; } // Appearances void LoadItemAppearances(); @@ -114,6 +131,7 @@ private: ToyBoxContainer _toys; HeirloomContainer _heirlooms; + MountContainer _mounts; boost::dynamic_bitset<uint32> _appearances; std::unordered_map<uint32, std::unordered_set<ObjectGuid>> _temporaryAppearances; std::unordered_map<uint32, FavoriteAppearanceState> _favoriteAppearances; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f4c2188c18a..81566daa587 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3149,6 +3149,10 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent UpdateCriteria(CRITERIA_TYPE_LEARN_SPELL, spellId); } + // needs to be when spell is already learned, to prevent infinite recursion crashes + if (sDB2Manager.GetMount(spellId)) + GetSession()->GetCollectionMgr()->AddMount(spellId, MOUNT_STATUS_NONE, false, IsInWorld() ? false : true); + // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell return active && !disabled && !superceded_old; } @@ -17551,6 +17555,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) _LoadSpells(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS)); GetSession()->GetCollectionMgr()->LoadToys(); GetSession()->GetCollectionMgr()->LoadHeirlooms(); + GetSession()->GetCollectionMgr()->LoadMounts(); GetSession()->GetCollectionMgr()->LoadItemAppearances(); LearnSpecializationSpells(); @@ -19604,6 +19609,7 @@ void Player::SaveToDB(bool create /*=false*/) GetSession()->GetCollectionMgr()->SaveAccountToys(trans); GetSession()->GetBattlePetMgr()->SaveToDB(trans); GetSession()->GetCollectionMgr()->SaveAccountHeirlooms(trans); + GetSession()->GetCollectionMgr()->SaveAccountMounts(trans); GetSession()->GetCollectionMgr()->SaveAccountItemAppearances(trans); stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_LAST_PLAYER_CHARACTERS); @@ -23041,6 +23047,11 @@ void Player::SendInitialPacketsBeforeAddToMap() SendDirectMessage(worldServerInfo.Write()); // SMSG_ACCOUNT_MOUNT_UPDATE + WorldPackets::Misc::AccountMountUpdate mountUpdate; + mountUpdate.IsFullUpdate = true; + mountUpdate.Mounts = &GetSession()->GetCollectionMgr()->GetAccountMounts(); + SendDirectMessage(mountUpdate.Write()); + // SMSG_ACCOUNT_TOYS_UPDATE WorldPackets::Toy::AccountToysUpdate toysUpdate; toysUpdate.IsFullUpdate = true; diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index b5a190c9a63..9b04213509b 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1154,3 +1154,8 @@ void WorldSession::HandleMountSpecialAnimOpcode(WorldPackets::Misc::MountSpecial specialMountAnim.UnitGUID = _player->GetGUID(); GetPlayer()->SendMessageToSet(specialMountAnim.Write(), false); } + +void WorldSession::HandleMountSetFavorite(WorldPackets::Misc::MountSetFavorite& mountSetFavorite) +{ + _collectionMgr->MountSetFavorite(mountSetFavorite.MountSpellID, mountSetFavorite.IsFavorite); +} diff --git a/src/server/game/Server/Packets/MiscPackets.cpp b/src/server/game/Server/Packets/MiscPackets.cpp index a773741b690..6cde22d5130 100644 --- a/src/server/game/Server/Packets/MiscPackets.cpp +++ b/src/server/game/Server/Packets/MiscPackets.cpp @@ -642,3 +642,25 @@ WorldPacket const* WorldPackets::Misc::DisplayGameError::Write() return &_worldPacket; } + +WorldPacket const* WorldPackets::Misc::AccountMountUpdate::Write() +{ + _worldPacket.WriteBit(IsFullUpdate); + _worldPacket << uint32(Mounts->size()); + + for (auto const& spell : *Mounts) + { + _worldPacket << int32(spell.first); + _worldPacket.WriteBits(spell.second, 2); + } + + _worldPacket.FlushBits(); + + return &_worldPacket; +} + +void WorldPackets::Misc::MountSetFavorite::Read() +{ + _worldPacket >> MountSpellID; + IsFavorite = _worldPacket.ReadBit(); +} diff --git a/src/server/game/Server/Packets/MiscPackets.h b/src/server/game/Server/Packets/MiscPackets.h index bf8c0549314..e4aa5ebd026 100644 --- a/src/server/game/Server/Packets/MiscPackets.h +++ b/src/server/game/Server/Packets/MiscPackets.h @@ -838,6 +838,28 @@ namespace WorldPackets Optional<int32> Arg; Optional<int32> Arg2; }; + + class AccountMountUpdate final : public ServerPacket + { + public: + AccountMountUpdate() : ServerPacket(SMSG_ACCOUNT_MOUNT_UPDATE) { } + + WorldPacket const* Write() override; + + bool IsFullUpdate = false; + MountContainer const* Mounts = nullptr; + }; + + class MountSetFavorite final : public ClientPacket + { + public: + MountSetFavorite(WorldPacket&& packet) : ClientPacket(CMSG_MOUNT_SET_FAVORITE, std::move(packet)) { } + + void Read() override; + + uint32 MountSpellID = 0; + bool IsFavorite = false; + }; } } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index d6647db388c..f9e8e740bbc 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -498,7 +498,7 @@ void OpcodeTable::Initialize() DEFINE_HANDLER(CMSG_MINIMAP_PING, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMinimapPingOpcode); DEFINE_HANDLER(CMSG_MISSILE_TRAJECTORY_COLLISION, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMissileTrajectoryCollision); DEFINE_HANDLER(CMSG_MOUNT_CLEAR_FANFARE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL); - DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); + DEFINE_HANDLER(CMSG_MOUNT_SET_FAVORITE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSetFavorite); DEFINE_HANDLER(CMSG_MOUNT_SPECIAL_ANIM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleMountSpecialAnimOpcode); DEFINE_HANDLER(CMSG_MOVE_APPLY_MOVEMENT_FORCE_ACK, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_NULL); DEFINE_HANDLER(CMSG_MOVE_CHANGE_TRANSPORT, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes); @@ -835,7 +835,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_CRITERIA_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE); diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 2b3a1c20ef0..dec0b2a8793 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1079,6 +1079,7 @@ public: BATTLE_PET_SLOTS, GLOBAL_ACCOUNT_HEIRLOOMS, GLOBAL_REALM_CHARACTER_COUNTS, + MOUNTS, ITEM_APPEARANCES, ITEM_FAVORITE_APPEARANCES, @@ -1107,6 +1108,10 @@ public: stmt->setUInt32(0, battlenetAccountId); ok = SetPreparedQuery(GLOBAL_ACCOUNT_HEIRLOOMS, stmt) && ok; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_MOUNTS); + stmt->setUInt32(0, battlenetAccountId); + ok = SetPreparedQuery(MOUNTS, stmt) && ok; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS_BY_ACCOUNT_ID); stmt->setUInt32(0, accountId); ok = SetPreparedQuery(GLOBAL_REALM_CHARACTER_COUNTS, stmt) && ok; @@ -1152,6 +1157,7 @@ void WorldSession::InitializeSessionCallback(SQLQueryHolder* realmHolder, SQLQue LoadTutorialsData(realmHolder->GetPreparedResult(AccountInfoQueryHolderPerRealm::TUTORIALS)); _collectionMgr->LoadAccountToys(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_TOYS)); _collectionMgr->LoadAccountHeirlooms(holder->GetPreparedResult(AccountInfoQueryHolder::GLOBAL_ACCOUNT_HEIRLOOMS)); + _collectionMgr->LoadAccountMounts(holder->GetPreparedResult(AccountInfoQueryHolder::MOUNTS)); _collectionMgr->LoadAccountItemAppearances(holder->GetPreparedResult(AccountInfoQueryHolder::ITEM_APPEARANCES), holder->GetPreparedResult(AccountInfoQueryHolder::ITEM_FAVORITE_APPEARANCES)); if (!m_inQueue) diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 324e79d7f59..b244b5fd96c 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -432,6 +432,7 @@ namespace WorldPackets class WorldTeleport; class MountSpecial; class SetTaxiBenchmarkMode; + class MountSetFavorite; } namespace Movement @@ -1681,6 +1682,8 @@ class TC_GAME_API WorldSession void HandleToySetFavorite(WorldPackets::Toy::ToySetFavorite& packet); void HandleUseToy(WorldPackets::Toy::UseToy& packet); + void HandleMountSetFavorite(WorldPackets::Misc::MountSetFavorite& mountSetFavorite); + // Scenes void HandleSceneTriggerEvent(WorldPackets::Scenes::SceneTriggerEvent& sceneTriggerEvent); void HandleScenePlaybackComplete(WorldPackets::Scenes::ScenePlaybackComplete& scenePlaybackComplete); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 50ffc1d7a24..9461a3fac60 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1938,6 +1938,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading faction change title pairs..."); sObjectMgr->LoadFactionChangeTitles(); + TC_LOG_INFO("server.loading", "Loading mount definitions..."); + CollectionMgr::LoadMountDefinitions(); + TC_LOG_INFO("server.loading", "Loading GM bugs..."); sSupportMgr->LoadBugTickets(); |