diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.cpp | 3 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/LoginDatabase.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.cpp | 88 | ||||
-rw-r--r-- | src/server/game/Entities/Player/CollectionMgr.h | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.h | 1 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 16 |
9 files changed, 127 insertions, 2 deletions
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp index f02ad1a4e68..95997a54d44 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.cpp +++ b/src/server/database/Database/Implementation/LoginDatabase.cpp @@ -186,6 +186,9 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES, "SELECT itemModifiedAppearanceId FROM battlenet_item_favorite_appearances WHERE battlenetAccountId = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_INS_BNET_ITEM_FAVORITE_APPEARANCE, "INSERT INTO battlenet_item_favorite_appearances (battlenetAccountId, itemModifiedAppearanceId) VALUES (?, ?)", CONNECTION_ASYNC); PrepareStatement(LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE, "DELETE FROM battlenet_item_favorite_appearances WHERE battlenetAccountId = ? AND itemModifiedAppearanceId = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS, "SELECT blobIndex, illusionMask FROM battlenet_account_transmog_illusions WHERE battlenetAccountId = ? ORDER BY blobIndex DESC", CONNECTION_ASYNC); + PrepareStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS, "INSERT INTO battlenet_account_transmog_illusions (battlenetAccountId, blobIndex, illusionMask) VALUES (?, ?, ?) " + "ON DUPLICATE KEY UPDATE illusionMask = illusionMask | VALUES(illusionMask)", CONNECTION_ASYNC); } LoginDatabaseConnection::LoginDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo) diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index d46e441d961..7d3c44f1f91 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -172,6 +172,8 @@ enum LoginDatabaseStatements : uint32 LOGIN_SEL_BNET_ITEM_FAVORITE_APPEARANCES, LOGIN_INS_BNET_ITEM_FAVORITE_APPEARANCE, LOGIN_DEL_BNET_ITEM_FAVORITE_APPEARANCE, + LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS, + LOGIN_INS_BNET_TRANSMOG_ILLUSIONS, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp index c7d2966ea0f..ff77b19e6f7 100644 --- a/src/server/game/Entities/Player/CollectionMgr.cpp +++ b/src/server/game/Entities/Player/CollectionMgr.cpp @@ -85,7 +85,7 @@ namespace } } -CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner), _appearances(std::make_unique<boost::dynamic_bitset<uint32>>()) +CollectionMgr::CollectionMgr(WorldSession* owner) : _owner(owner), _appearances(std::make_unique<boost::dynamic_bitset<uint32>>()), _transmogIllusions(std::make_unique<boost::dynamic_bitset<uint32>>()) { } @@ -882,3 +882,89 @@ void CollectionMgr::SendFavoriteAppearances() const _owner->SendPacket(accountTransmogUpdate.Write()); } + +void CollectionMgr::LoadTransmogIllusions() +{ + Player* owner = _owner->GetPlayer(); + boost::to_block_range(*_transmogIllusions, DynamicBitsetBlockOutputIterator([owner](uint32 blockValue) + { + owner->AddIllusionBlock(blockValue); + })); +} + +void CollectionMgr::LoadAccountTransmogIllusions(PreparedQueryResult knownTransmogIllusions) +{ + if (knownTransmogIllusions) + { + std::vector<uint32> blocks; + do + { + Field* fields = knownTransmogIllusions->Fetch(); + uint16 blobIndex = fields[0].GetUInt16(); + if (blobIndex >= blocks.size()) + blocks.resize(blobIndex + 1); + + blocks[blobIndex] = fields[1].GetUInt32(); + + } while (knownTransmogIllusions->NextRow()); + + _transmogIllusions->init_from_block_range(blocks.begin(), blocks.end()); + } + + // Static illusions known by every player + static uint16 constexpr defaultIllusions[] = + { + 3, // Lifestealing + 13, // Crusader + 22, // Striking + 23, // Agility + 34, // Hide Weapon Enchant + 43, // Beastslayer + 44, // Titanguard + }; + + for (uint16 illusionId : defaultIllusions) + { + if (_transmogIllusions->size() <= illusionId) + _transmogIllusions->resize(illusionId + 1); + + _transmogIllusions->set(illusionId); + } +} + +void CollectionMgr::SaveAccountTransmogIllusions(LoginDatabaseTransaction trans) +{ + uint16 blockIndex = 0; + + boost::to_block_range(*_transmogIllusions, DynamicBitsetBlockOutputIterator([this, &blockIndex, trans](uint32 blockValue) + { + if (blockValue) // this table is only appended/bits are set (never cleared) so don't save empty blocks + { + LoginDatabasePreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_TRANSMOG_ILLUSIONS); + stmt->setUInt32(0, _owner->GetBattlenetAccountId()); + stmt->setUInt16(1, blockIndex); + stmt->setUInt32(2, blockValue); + trans->Append(stmt); + } + ++blockIndex; + })); +} + +void CollectionMgr::AddTransmogIllusion(uint16 illusionId) +{ + Player* owner = _owner->GetPlayer(); + if (_transmogIllusions->size() <= illusionId) + { + std::size_t numBlocks = _transmogIllusions->num_blocks(); + _transmogIllusions->resize(illusionId + 1); + numBlocks = _transmogIllusions->num_blocks() - numBlocks; + while (numBlocks--) + owner->AddIllusionBlock(0); + } + + _transmogIllusions->set(illusionId); + uint32 blockIndex = illusionId / 32; + uint32 bitIndex = illusionId % 32; + + owner->AddIllusionFlag(blockIndex, 1 << bitIndex); +} diff --git a/src/server/game/Entities/Player/CollectionMgr.h b/src/server/game/Entities/Player/CollectionMgr.h index 7c3c5d9c014..7c757f0d64e 100644 --- a/src/server/game/Entities/Player/CollectionMgr.h +++ b/src/server/game/Entities/Player/CollectionMgr.h @@ -138,6 +138,12 @@ public: // returns ItemAppearance::ID, not ItemModifiedAppearance::ID std::unordered_set<uint32> GetAppearanceIds() const; + // Illusions + void LoadTransmogIllusions(); + void LoadAccountTransmogIllusions(PreparedQueryResult knownIllusions); + void SaveAccountTransmogIllusions(LoginDatabaseTransaction trans); + void AddTransmogIllusion(uint16 illusionId); + enum class FavoriteAppearanceState { New, @@ -161,6 +167,7 @@ private: std::unique_ptr<boost::dynamic_bitset<uint32>> _appearances; std::unordered_map<uint32, std::unordered_set<ObjectGuid>> _temporaryAppearances; std::unordered_map<uint32, FavoriteAppearanceState> _favoriteAppearances; + std::unique_ptr<boost::dynamic_bitset<uint32>> _transmogIllusions; }; #endif // CollectionMgr_h__ diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e35a3a80aa4..cf02d2e5e6b 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -18500,6 +18500,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol GetSession()->GetCollectionMgr()->LoadHeirlooms(); GetSession()->GetCollectionMgr()->LoadMounts(); GetSession()->GetCollectionMgr()->LoadItemAppearances(); + GetSession()->GetCollectionMgr()->LoadTransmogIllusions(); LearnSpecializationSpells(); @@ -20784,6 +20785,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba GetSession()->GetCollectionMgr()->SaveAccountHeirlooms(loginTransaction); GetSession()->GetCollectionMgr()->SaveAccountMounts(loginTransaction); GetSession()->GetCollectionMgr()->SaveAccountItemAppearances(loginTransaction); + GetSession()->GetCollectionMgr()->SaveAccountTransmogIllusions(loginTransaction); LoginDatabasePreparedStatement* loginStmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_BNET_LAST_PLAYER_CHARACTERS); loginStmt->setUInt32(0, GetSession()->GetAccountId()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b9936e39af2..3f366b41c72 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2761,6 +2761,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> if (index >= 0) RemoveDynamicUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::ConditionalTransmog), uint32(index)); } + + void AddIllusionBlock(uint32 blockValue) { AddDynamicUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransmogIllusions)) = blockValue; } + void AddIllusionFlag(uint32 slot, uint32 flag) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::TransmogIllusions, slot), flag); } + void AddSelfResSpell(int32 spellId) { AddDynamicUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::SelfResSpells)) = spellId; } void RemoveSelfResSpell(int32 spellId) { diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index fa92d25dc13..e3be227df53 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -1075,6 +1075,7 @@ public: MOUNTS, ITEM_APPEARANCES, ITEM_FAVORITE_APPEARANCES, + TRANSMOG_ILLUSIONS, MAX_QUERIES }; @@ -1118,6 +1119,10 @@ public: stmt->setUInt32(0, battlenetAccountId); ok = SetPreparedQuery(ITEM_FAVORITE_APPEARANCES, stmt) && ok; + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_TRANSMOG_ILLUSIONS); + stmt->setUInt32(0, battlenetAccountId); + ok = SetPreparedQuery(TRANSMOG_ILLUSIONS, stmt) && ok; + return ok; } }; @@ -1169,6 +1174,7 @@ void WorldSession::InitializeSessionCallback(LoginDatabaseQueryHolder const& hol _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)); + _collectionMgr->LoadAccountTransmogIllusions(holder.GetPreparedResult(AccountInfoQueryHolder::TRANSMOG_ILLUSIONS)); if (!m_inQueue) SendAuthResponse(ERROR_OK, false); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 86a6404fd6d..58e39fc634b 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -402,6 +402,7 @@ class TC_GAME_API Spell void EffectCreatePrivateConversation(); void EffectSendChatMessage(); void EffectGrantBattlePetExperience(); + void EffectLearnTransmogIllusion(); typedef std::unordered_set<Aura*> UsedSpellMods; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1f06b884942..dadff88a498 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -358,7 +358,7 @@ NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EF &Spell::EffectNULL, //273 SPELL_EFFECT_CRAFT_RUNEFORGE_LEGENDARY &Spell::EffectUnused, //274 SPELL_EFFECT_274 &Spell::EffectUnused, //275 SPELL_EFFECT_275 - &Spell::EffectNULL, //276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION + &Spell::EffectLearnTransmogIllusion, //276 SPELL_EFFECT_LEARN_TRANSMOG_ILLUSION &Spell::EffectNULL, //277 SPELL_EFFECT_SET_CHROMIE_TIME &Spell::EffectNULL, //278 SPELL_EFFECT_278 &Spell::EffectNULL, //279 SPELL_EFFECT_LEARN_GARR_TALENT @@ -5843,3 +5843,17 @@ void Spell::EffectGrantBattlePetExperience() playerCaster->GetSession()->GetBattlePetMgr()->GrantBattlePetExperience(unitTarget->GetBattlePetCompanionGUID(), damage, BattlePets::BattlePetXpSource::SpellEffect); } + +void Spell::EffectLearnTransmogIllusion() +{ + if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) + return; + + Player* player = Object::ToPlayer(unitTarget); + if (!player) + return; + + uint16 illusionId = effectInfo->MiscValue; + + player->GetSession()->GetCollectionMgr()->AddTransmogIllusion(illusionId); +} |