aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2022-12-17 20:27:13 +0100
committerShauren <shauren.trinity@gmail.com>2022-12-17 20:27:13 +0100
commit0555ab2f56e5ad326948df96f5c2e35254e0cf4f (patch)
treee04eba976ec67bcade40d1b3bfed778a438abe86 /src
parente275c39586dba170c931b972aa7e9cc3c691a533 (diff)
Core/Players: Implemented setting tradeskill recipes as favorite
Diffstat (limited to 'src')
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp4
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h4
-rw-r--r--src/server/game/Entities/Player/Player.cpp71
-rw-r--r--src/server/game/Entities/Player/Player.h7
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp8
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp6
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h11
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp2
-rw-r--r--src/server/game/Server/WorldSession.h2
10 files changed, 102 insertions, 17 deletions
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index b3032c7a795..4bf020a31ae 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -95,6 +95,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_CHARACTER_AURAS, "SELECT casterGuid, itemGuid, spell, effectMask, recalculateMask, difficulty, stackCount, maxDuration, remainTime, remainCharges, castItemId, castItemLevel FROM character_aura WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_AURA_EFFECTS, "SELECT casterGuid, itemGuid, spell, effectMask, effectIndex, amount, baseAmount FROM character_aura_effect WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_SPELL, "SELECT spell, active, disabled FROM character_spell WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_SPELL_FAVORITES, "SELECT spell FROM character_spell_favorite WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS, "SELECT quest, status, explored, acceptTime, endTime FROM character_queststatus WHERE guid = ? AND status <> 0", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES, "SELECT quest, objective, data FROM character_queststatus_objectives WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES_CRITERIA, "SELECT questObjectiveId FROM character_queststatus_objectives_criteria WHERE guid = ?", CONNECTION_ASYNC);
@@ -638,6 +639,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_INS_CHAR_SKILLS, "INSERT INTO character_skills (guid, skill, value, max) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_CHAR_SKILLS, "UPDATE character_skills SET value = ?, max = ? WHERE guid = ? AND skill = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_SPELL, "INSERT INTO character_spell (guid, spell, active, disabled) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_SPELL_FAVORITE, "DELETE FROM character_spell_favorite WHERE guid = ? AND spell = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHAR_SPELL_FAVORITE_BY_CHAR, "DELETE FROM character_spell_favorite WHERE guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHAR_SPELL_FAVORITE, "INSERT INTO character_spell_favorite (guid, spell) VALUES (?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHAR_STATS, "DELETE FROM character_stats WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_CHAR_STATS, "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, strength, agility, stamina, intellect, "
"armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, rangedCritPct, spellCritPct, attackPower, rangedAttackPower, "
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 5c19d4780ea..b9628d20b10 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -67,6 +67,7 @@ enum CharacterDatabaseStatements : uint32
CHAR_SEL_CHARACTER_AURAS,
CHAR_SEL_CHARACTER_AURA_EFFECTS,
CHAR_SEL_CHARACTER_SPELL,
+ CHAR_SEL_CHARACTER_SPELL_FAVORITES,
CHAR_SEL_CHARACTER_QUESTSTATUS,
CHAR_SEL_CHARACTER_QUESTSTATUS_OBJECTIVES,
@@ -522,6 +523,9 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_CHAR_SKILLS,
CHAR_UPD_CHAR_SKILLS,
CHAR_INS_CHAR_SPELL,
+ CHAR_DEL_CHAR_SPELL_FAVORITE,
+ CHAR_DEL_CHAR_SPELL_FAVORITE_BY_CHAR,
+ CHAR_INS_CHAR_SPELL_FAVORITE,
CHAR_DEL_CHAR_STATS,
CHAR_INS_CHAR_STATS,
CHAR_DEL_PETITION_BY_OWNER,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 5df064eb9c4..a9089bc5dbb 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2624,7 +2624,7 @@ void Player::InitStatsForLevel(bool reapplyMods)
void Player::SendKnownSpells()
{
WorldPackets::Spells::SendKnownSpells knownSpells;
- knownSpells.InitialLogin = false; /// @todo
+ knownSpells.InitialLogin = IsLoading();
knownSpells.KnownSpells.reserve(m_spells.size());
for (PlayerSpellMap::value_type const& spell : m_spells)
@@ -2636,6 +2636,8 @@ void Player::SendKnownSpells()
continue;
knownSpells.KnownSpells.push_back(spell.first);
+ if (spell.second.favorite)
+ knownSpells.FavoriteSpells.push_back(spell.first);
}
SendDirectMessage(knownSpells.Write());
@@ -2804,7 +2806,7 @@ WorldLocation const* Player::GetStoredAuraTeleportLocation(uint32 spellId) const
return nullptr;
}
-bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, int32 fromSkill /*= 0*/, Optional<int32> traitDefinitionId /*= {}*/)
+bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, int32 fromSkill /*= 0*/, bool favorite /*= false*/, Optional<int32> traitDefinitionId /*= {}*/)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
if (!spellInfo)
@@ -2893,6 +2895,8 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
itr->second.TraitDefinitionId = traitDefinitionId;
}
+ itr->second.favorite = favorite;
+
// update active state for known spell
if (itr->second.active != active && itr->second.state != PLAYERSPELL_REMOVED && !itr->second.disabled)
{
@@ -2974,6 +2978,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
newspell.active = active;
newspell.dependent = dependent;
newspell.disabled = disabled;
+ newspell.favorite = favorite;
if (traitDefinitionId)
newspell.TraitDefinitionId = *traitDefinitionId;
@@ -3227,8 +3232,9 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/
bool disabled = (itr != m_spells.end()) ? itr->second.disabled : false;
bool active = disabled ? itr->second.active : true;
+ bool favorite = itr != m_spells.end() ? itr->second.favorite : false;
- bool learning = AddSpell(spell_id, active, true, dependent, false, false, fromSkill, traitDefinitionId);
+ bool learning = AddSpell(spell_id, active, true, dependent, false, false, fromSkill, favorite, traitDefinitionId);
// prevent duplicated entires in spell book, also not send if not in world (loading)
if (learning && IsInWorld())
@@ -3236,6 +3242,7 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill /*= 0*/
WorldPackets::Spells::LearnedSpells learnedSpells;
WorldPackets::Spells::LearnedSpellInfo& learnedSpellInfo = learnedSpells.ClientLearnedSpellData.emplace_back();
learnedSpellInfo.SpellID = spell_id;
+ learnedSpellInfo.IsFavorite = favorite;
learnedSpellInfo.TraitDefinitionID = traitDefinitionId;
learnedSpells.SuppressMessaging = suppressMessaging;
SendDirectMessage(learnedSpells.Write());
@@ -3433,6 +3440,17 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled /*= false*/, bool learn_
}
}
+void Player::SetSpellFavorite(uint32 spellId, bool favorite)
+{
+ auto itr = m_spells.find(spellId);
+ if (itr == m_spells.end())
+ return;
+
+ itr->second.favorite = favorite;
+ if (itr->second.state == PLAYERSPELL_UNCHANGED)
+ itr->second.state = PLAYERSPELL_CHANGED;
+}
+
void Player::RemoveArenaSpellCooldowns(bool removeActivePetCooldowns)
{
// remove cooldowns on spells that have < 10 min CD
@@ -17617,7 +17635,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol
UpdateDisplayPower();
_LoadTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
_LoadPvpTalents(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_PVP_TALENTS));
- _LoadSpells(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS));
+ _LoadSpells(holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELLS), holder.GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SPELL_FAVORITES));
GetSession()->GetCollectionMgr()->LoadToys();
GetSession()->GetCollectionMgr()->LoadHeirlooms();
GetSession()->GetCollectionMgr()->LoadMounts();
@@ -18917,16 +18935,25 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result)
m_MonthlyQuestChanged = false;
}
-void Player::_LoadSpells(PreparedQueryResult result)
+void Player::_LoadSpells(PreparedQueryResult result, PreparedQueryResult favoritesResult)
{
- //QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled FROM character_spell WHERE guid = '%u'", GetGUIDLow());
-
+ //QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled, favorite FROM character_spell WHERE guid = '%u'", GetGUIDLow());
if (result)
{
do
AddSpell((*result)[0].GetUInt32(), (*result)[1].GetBool(), false, false, (*result)[2].GetBool(), true);
while (result->NextRow());
}
+
+ if (favoritesResult)
+ {
+ do
+ {
+ auto itr = m_spells.find((*favoritesResult)[0].GetUInt32());
+ if (itr != m_spells.end())
+ itr->second.favorite = true;
+ } while (favoritesResult->NextRow());
+ }
}
void Player::_LoadStoredAuraTeleportLocations(PreparedQueryResult result)
@@ -20401,15 +20428,31 @@ void Player::_SaveSpells(CharacterDatabaseTransaction trans)
trans->Append(stmt);
}
- // add only changed/new not dependent spells
- if (!itr->second.dependent && (itr->second.state == PLAYERSPELL_NEW || itr->second.state == PLAYERSPELL_CHANGED))
+ if ((itr->second.state == PLAYERSPELL_NEW || itr->second.state == PLAYERSPELL_CHANGED))
{
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SPELL);
- stmt->setUInt64(0, GetGUID().GetCounter());
- stmt->setUInt32(1, itr->first);
- stmt->setBool(2, itr->second.active);
- stmt->setBool(3, itr->second.disabled);
+ // add only changed/new not dependent spells
+ if (!itr->second.dependent)
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SPELL);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ stmt->setUInt32(1, itr->first);
+ stmt->setBool(2, itr->second.active);
+ stmt->setBool(3, itr->second.disabled);
+ trans->Append(stmt);
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_FAVORITE);
+ stmt->setUInt32(0, itr->first);
+ stmt->setUInt64(1, GetGUID().GetCounter());
trans->Append(stmt);
+
+ if (itr->second.favorite)
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SPELL_FAVORITE);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ stmt->setUInt32(1, itr->first);
+ trans->Append(stmt);
+ }
}
if (itr->second.state == PLAYERSPELL_REMOVED)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 1c108fc4cdb..f2047aac692 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -188,6 +188,7 @@ struct PlayerSpell
bool active : 1; // show in spellbook
bool dependent : 1; // learned as result another spell learn, skill grow, quest reward, etc
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
+ bool favorite : 1;
Optional<int32> TraitDefinitionId;
};
@@ -854,6 +855,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_AURA_EFFECTS,
PLAYER_LOGIN_QUERY_LOAD_AURA_STORED_LOCATIONS,
PLAYER_LOGIN_QUERY_LOAD_SPELLS,
+ PLAYER_LOGIN_QUERY_LOAD_SPELL_FAVORITES,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES_CRITERIA,
@@ -1801,7 +1803,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const;
void SendKnownSpells();
void SendUnlearnSpells();
- bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, int32 fromSkill = 0, Optional<int32> traitDefinitionId = {});
+ bool AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading = false, int32 fromSkill = 0, bool favorite = false, Optional<int32> traitDefinitionId = {});
void LearnSpell(uint32 spell_id, bool dependent, int32 fromSkill = 0, bool suppressMessaging = false, Optional<int32> traitDefinitionId = {});
void RemoveSpell(uint32 spell_id, bool disabled = false, bool learn_low_rank = true, bool suppressMessaging = false);
void ResetSpells(bool myClassOnly = false);
@@ -1818,6 +1820,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void LearnSpecializationSpells();
void RemoveSpecializationSpells();
void SendSpellCategoryCooldowns() const;
+ void SetSpellFavorite(uint32 spellId, bool favorite);
void AddStoredAuraTeleportLocation(uint32 spellId);
void RemoveStoredAuraTeleportLocation(uint32 spellId);
@@ -2920,7 +2923,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadRandomBGStatus(PreparedQueryResult result);
void _LoadGroup(PreparedQueryResult result);
void _LoadSkills(PreparedQueryResult result);
- void _LoadSpells(PreparedQueryResult result);
+ void _LoadSpells(PreparedQueryResult result, PreparedQueryResult favoritesResult);
void _LoadStoredAuraTeleportLocations(PreparedQueryResult result);
bool _LoadHomeBind(PreparedQueryResult result);
void _LoadDeclinedNames(PreparedQueryResult result);
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 9a7d20cc1a6..e63223554af 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -112,6 +112,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SPELLS, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SPELL_FAVORITES);
+ stmt->setUInt64(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SPELL_FAVORITES, stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_QUESTSTATUS);
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS, stmt);
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index e4461af9337..9c4a5a8648f 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -111,3 +111,11 @@ void WorldSession::HandleUnlearnSkillOpcode(WorldPackets::Spells::UnlearnSkill&
GetPlayer()->SetSkill(packet.SkillLine, 0, 0, 0);
}
+
+void WorldSession::HandleTradeSkillSetFavorite(WorldPackets::Spells::TradeSkillSetFavorite const& tradeSkillSetFavorite)
+{
+ if (!_player->HasSpell(tradeSkillSetFavorite.RecipeID))
+ return;
+
+ _player->SetSpellFavorite(tradeSkillSetFavorite.RecipeID, tradeSkillSetFavorite.IsFavorite);
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 84b5066863f..221a6e5cd96 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -1048,4 +1048,10 @@ WorldPacket const* MissileCancel::Write()
return &_worldPacket;
}
+
+void TradeSkillSetFavorite::Read()
+{
+ _worldPacket >> RecipeID;
+ IsFavorite = _worldPacket.ReadBit();
+}
}
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index 4d2380a964f..53cfdfddfcd 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -1073,6 +1073,17 @@ namespace WorldPackets
int32 SpellID = 0;
};
+ class TradeSkillSetFavorite final : public ClientPacket
+ {
+ public:
+ TradeSkillSetFavorite(WorldPacket&& packet) : ClientPacket(CMSG_TRADE_SKILL_SET_FAVORITE, std::move(packet)) { }
+
+ void Read() override;
+
+ int32 RecipeID = 0;
+ bool IsFavorite = false;
+ };
+
ByteBuffer& operator>>(ByteBuffer& buffer, SpellCastRequest& request);
}
}
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index 5df4f540e4e..7e70da65e95 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -928,7 +928,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_TOGGLE_PVP, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTogglePvP);
DEFINE_HANDLER(CMSG_TOTEM_DESTROYED, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTotemDestroyed);
DEFINE_HANDLER(CMSG_TOY_CLEAR_FANFARE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleToyClearFanfare);
- DEFINE_HANDLER(CMSG_TRADE_SKILL_SET_FAVORITE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::Handle_NULL);
+ DEFINE_HANDLER(CMSG_TRADE_SKILL_SET_FAVORITE, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTradeSkillSetFavorite);
DEFINE_HANDLER(CMSG_TRAINER_BUY_SPELL, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTrainerBuySpellOpcode);
DEFINE_HANDLER(CMSG_TRAINER_LIST, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTrainerListOpcode);
DEFINE_HANDLER(CMSG_TRAITS_COMMIT_CONFIG, STATUS_LOGGEDIN, PROCESS_INPLACE, &WorldSession::HandleTraitsCommitConfig);
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index b26204a0989..5bf759a9a01 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -717,6 +717,7 @@ namespace WorldPackets
class SpellClick;
class MissileTrajectoryCollision;
class UpdateMissileTrajectory;
+ class TradeSkillSetFavorite;
}
namespace Talent
@@ -1506,6 +1507,7 @@ class TC_GAME_API WorldSession
void HandleLearnTalentsOpcode(WorldPackets::Talent::LearnTalents& packet);
void HandleConfirmRespecWipeOpcode(WorldPackets::Talent::ConfirmRespecWipe& confirmRespecWipe);
void HandleUnlearnSkillOpcode(WorldPackets::Spells::UnlearnSkill& packet);
+ void HandleTradeSkillSetFavorite(WorldPackets::Spells::TradeSkillSetFavorite const& tradeSkillSetFavorite);
void HandleTraitsCommitConfig(WorldPackets::Traits::TraitsCommitConfig const& traitsCommitConfig);
void HandleClassTalentsRequestNewConfig(WorldPackets::Traits::ClassTalentsRequestNewConfig& classTalentsRequestNewConfig);