mirror of
https://github.com/liyunfan1223/azerothcore-wotlk.git
synced 2026-08-08 15:58:04 +00:00
fix(Core/Player): Fixed some spells appearing as available at trainer when they are already known (#22678)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
* cherry-pick commit (baebb2d602)
This commit is contained in:
@@ -2841,6 +2841,66 @@ void Player::SendInitialSpells()
|
|||||||
SendDirectMessage(&data);
|
SendDirectMessage(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::SendUnlearnSpells()
|
||||||
|
{
|
||||||
|
WorldPacket data(SMSG_SEND_UNLEARN_SPELLS, 4 + 4 * m_spells.size());
|
||||||
|
|
||||||
|
uint32 spellCount = 0;
|
||||||
|
size_t countPos = data.wpos();
|
||||||
|
data << uint32(spellCount);
|
||||||
|
|
||||||
|
for (auto const& itr : m_spells)
|
||||||
|
{
|
||||||
|
if (itr.second->State == PLAYERSPELL_REMOVED || itr.second->Active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto skillLineAbilities = sSpellMgr->GetSkillLineAbilityMapBounds(itr.first);
|
||||||
|
if (skillLineAbilities.first == skillLineAbilities.second)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Client already hides ranks that have a superseding rank
|
||||||
|
bool hasSupercedingRank = false;
|
||||||
|
for (auto slaItr = skillLineAbilities.first; slaItr != skillLineAbilities.second; ++slaItr)
|
||||||
|
{
|
||||||
|
if (slaItr->second->SupercededBySpell)
|
||||||
|
{
|
||||||
|
hasSupercedingRank = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasSupercedingRank)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 nextRank = sSpellMgr->GetNextSpellInChain(itr.first);
|
||||||
|
if (!nextRank || !HasSpell(nextRank))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
data << uint32(itr.first);
|
||||||
|
++spellCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.put<uint32>(countPos, spellCount);
|
||||||
|
SendDirectMessage(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Player::IsUnlearnNeededForSpell(uint32 spellId)
|
||||||
|
{
|
||||||
|
SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId);
|
||||||
|
if (spellInfo->IsRanked() && !spellInfo->IsStackableWithRanks())
|
||||||
|
{
|
||||||
|
auto skillLineAbilities = sSpellMgr->GetSkillLineAbilityMapBounds(spellId);
|
||||||
|
if (skillLineAbilities.first != skillLineAbilities.second)
|
||||||
|
{
|
||||||
|
for (auto itr = skillLineAbilities.first; itr != skillLineAbilities.second; ++itr)
|
||||||
|
if (itr->second->SupercededBySpell)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::RemoveMail(uint32 id)
|
void Player::RemoveMail(uint32 id)
|
||||||
{
|
{
|
||||||
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
|
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); ++itr)
|
||||||
@@ -3066,6 +3126,10 @@ bool Player::addSpell(uint32 spellId, uint8 addSpecMask, bool updateActive, bool
|
|||||||
if (nextSpellInfo->GetRank() < spellInfo->GetRank())
|
if (nextSpellInfo->GetRank() < spellInfo->GetRank())
|
||||||
{
|
{
|
||||||
itr->second->Active = false;
|
itr->second->Active = false;
|
||||||
|
|
||||||
|
if (!isBeingLoaded() && IsUnlearnNeededForSpell(spellId))
|
||||||
|
SendUnlearnSpells();
|
||||||
|
|
||||||
if (IsInWorld())
|
if (IsInWorld())
|
||||||
{
|
{
|
||||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
||||||
@@ -3080,6 +3144,10 @@ bool Player::addSpell(uint32 spellId, uint8 addSpecMask, bool updateActive, bool
|
|||||||
PlayerSpellMap::iterator itr2 = m_spells.find(spellInfo->Id);
|
PlayerSpellMap::iterator itr2 = m_spells.find(spellInfo->Id);
|
||||||
if (itr2 != m_spells.end())
|
if (itr2 != m_spells.end())
|
||||||
itr2->second->Active = false;
|
itr2->second->Active = false;
|
||||||
|
|
||||||
|
if (!isBeingLoaded() && IsUnlearnNeededForSpell(spellId))
|
||||||
|
SendUnlearnSpells();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3087,6 +3155,9 @@ bool Player::addSpell(uint32 spellId, uint8 addSpecMask, bool updateActive, bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isBeingLoaded() && IsUnlearnNeededForSpell(spellId))
|
||||||
|
SendUnlearnSpells();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -11628,10 +11699,7 @@ void Player::SendInitialPacketsBeforeAddToMap()
|
|||||||
SendDirectMessage(&data);
|
SendDirectMessage(&data);
|
||||||
|
|
||||||
SendInitialSpells();
|
SendInitialSpells();
|
||||||
|
SendUnlearnSpells();
|
||||||
data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4);
|
|
||||||
data << uint32(0); // count, for (count) uint32;
|
|
||||||
SendDirectMessage(&data);
|
|
||||||
|
|
||||||
SendInitialActionButtons();
|
SendInitialActionButtons();
|
||||||
m_reputationMgr->SendInitialReputations();
|
m_reputationMgr->SendInitialReputations();
|
||||||
|
|||||||
@@ -1664,6 +1664,9 @@ public:
|
|||||||
void UpdateNextMailTimeAndUnreads();
|
void UpdateNextMailTimeAndUnreads();
|
||||||
void AddNewMailDeliverTime(time_t deliver_time);
|
void AddNewMailDeliverTime(time_t deliver_time);
|
||||||
|
|
||||||
|
void SendUnlearnSpells();
|
||||||
|
static bool IsUnlearnNeededForSpell(uint32 spellId);
|
||||||
|
|
||||||
void RemoveMail(uint32 id);
|
void RemoveMail(uint32 id);
|
||||||
|
|
||||||
void AddMail(Mail* mail) { m_mail.push_front(mail); }// for call from WorldSession::SendMailTo
|
void AddMail(Mail* mail) { m_mail.push_front(mail); }// for call from WorldSession::SendMailTo
|
||||||
|
|||||||
Reference in New Issue
Block a user