aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp4
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h3
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp154
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.h20
-rw-r--r--src/server/game/Entities/Player/Player.cpp11
-rw-r--r--src/server/game/Handlers/MiscHandler.cpp5
-rw-r--r--src/server/game/Server/Packets/MiscPackets.cpp22
-rw-r--r--src/server/game/Server/Packets/MiscPackets.h22
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp4
-rw-r--r--src/server/game/Server/WorldSession.cpp6
-rw-r--r--src/server/game/Server/WorldSession.h3
-rw-r--r--src/server/game/World/World.cpp3
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();