aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp3
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h2
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp88
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.h7
-rw-r--r--src/server/game/Entities/Player/Player.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.h4
-rw-r--r--src/server/game/Server/WorldSession.cpp6
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp16
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);
+}