mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-20 17:27:36 +01:00
*Some cleanup and optimization to talent resetting and spec swapping. Has no impact on the functionality (it just wastes less CPU).
--HG-- branch : trunk
This commit is contained in:
@@ -2966,7 +2966,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
if (!spellInfo)
|
||||
{
|
||||
// do character spell book cleanup (all characters)
|
||||
if(!IsInWorld() && !learning) // spell load case
|
||||
if (!IsInWorld() && !learning) // spell load case
|
||||
{
|
||||
sLog.outError("Player::addSpell: Non-existed in SpellStore spell #%u request, deleting for all characters in `character_spell`.",spell_id);
|
||||
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE spell = '%u'",spell_id);
|
||||
@@ -2977,7 +2977,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!SpellMgr::IsSpellValid(spellInfo,this,false))
|
||||
if (!SpellMgr::IsSpellValid(spellInfo,this,false))
|
||||
{
|
||||
// do character spell book cleanup (all characters)
|
||||
if(!IsInWorld() && !learning) // spell load case
|
||||
@@ -3006,11 +3006,11 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
{
|
||||
uint32 next_active_spell_id = 0;
|
||||
// fix activate state for non-stackable low rank (and find next spell for !active case)
|
||||
if(!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
if (!SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
{
|
||||
if(uint32 next = spellmgr.GetNextSpellInChain(spell_id))
|
||||
if (uint32 next = spellmgr.GetNextSpellInChain(spell_id))
|
||||
{
|
||||
if(HasSpell(next))
|
||||
if (HasSpell(next))
|
||||
{
|
||||
// high rank already known so this must !active
|
||||
active = false;
|
||||
@@ -3020,10 +3020,10 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
}
|
||||
|
||||
// not do anything if already known in expected state
|
||||
if(itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
|
||||
if (itr->second->state != PLAYERSPELL_REMOVED && itr->second->active == active &&
|
||||
itr->second->dependent == dependent && itr->second->disabled == disabled)
|
||||
{
|
||||
if(!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
|
||||
if (!IsInWorld() && !learning) // explicitly load from DB and then exist in it already and set correctly
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
|
||||
return false;
|
||||
@@ -3039,21 +3039,21 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
}
|
||||
|
||||
// update active state for known spell
|
||||
if(itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
|
||||
if (itr->second->active != active && itr->second->state != PLAYERSPELL_REMOVED && !itr->second->disabled)
|
||||
{
|
||||
itr->second->active = active;
|
||||
|
||||
if(!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
|
||||
if (!IsInWorld() && !learning && !dependent_set) // explicitly load from DB and then exist in it already and set correctly
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
else if(itr->second->state != PLAYERSPELL_NEW)
|
||||
else if (itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
|
||||
if(active)
|
||||
if (active)
|
||||
{
|
||||
if (IsPassiveSpell(spell_id) && IsNeedCastPassiveSpellAtLearn(spellInfo))
|
||||
CastSpell (this,spell_id,true);
|
||||
CastSpell(this, spell_id, true);
|
||||
}
|
||||
else if(IsInWorld())
|
||||
else if (IsInWorld())
|
||||
{
|
||||
if(next_active_spell_id)
|
||||
{
|
||||
@@ -3061,7 +3061,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
||||
data << uint32(spell_id);
|
||||
data << uint32(next_active_spell_id);
|
||||
GetSession()->SendPacket( &data );
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3074,18 +3074,18 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
return active; // learn (show in spell book if active now)
|
||||
}
|
||||
|
||||
if(itr->second->disabled != disabled && itr->second->state != PLAYERSPELL_REMOVED)
|
||||
if (itr->second->disabled != disabled && itr->second->state != PLAYERSPELL_REMOVED)
|
||||
{
|
||||
if(itr->second->state != PLAYERSPELL_NEW)
|
||||
if (itr->second->state != PLAYERSPELL_NEW)
|
||||
itr->second->state = PLAYERSPELL_CHANGED;
|
||||
itr->second->disabled = disabled;
|
||||
|
||||
if(disabled)
|
||||
if (disabled)
|
||||
return false;
|
||||
|
||||
disabled_case = true;
|
||||
}
|
||||
else switch(itr->second->state)
|
||||
else switch (itr->second->state)
|
||||
{
|
||||
case PLAYERSPELL_UNCHANGED: // known saved spell
|
||||
return false;
|
||||
@@ -3099,7 +3099,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
default: // known not saved yet spell (new or modified)
|
||||
{
|
||||
// can be in case spell loading but learned at some previous spell loading
|
||||
if(!IsInWorld() && !learning && !dependent_set)
|
||||
if (!IsInWorld() && !learning && !dependent_set)
|
||||
itr->second->state = PLAYERSPELL_UNCHANGED;
|
||||
|
||||
return false;
|
||||
@@ -3107,18 +3107,19 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
}
|
||||
}
|
||||
|
||||
if(!disabled_case) // skip new spell adding if spell already known (disabled spells case)
|
||||
// skip new spell adding if spell already known (disabled spells case)
|
||||
if (!disabled_case)
|
||||
{
|
||||
// talent: unlearn all other talent ranks (high and low)
|
||||
if(TalentSpellPos const *talentPos = GetTalentSpellPos(spell_id))
|
||||
if (TalentSpellPos const *talentPos = GetTalentSpellPos(spell_id))
|
||||
{
|
||||
if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
||||
if (TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id ))
|
||||
{
|
||||
for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
|
||||
{
|
||||
// skip learning spell and no rank spell case
|
||||
uint32 rankSpellId = talentInfo->RankID[rank];
|
||||
if(!rankSpellId || rankSpellId == spell_id)
|
||||
if (!rankSpellId || rankSpellId == spell_id)
|
||||
continue;
|
||||
|
||||
removeSpell(rankSpellId,false,false);
|
||||
@@ -3126,9 +3127,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
}
|
||||
}
|
||||
// non talent spell: learn low ranks (recursive call)
|
||||
else if(uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
|
||||
else if (uint32 prev_spell = spellmgr.GetPrevSpellInChain(spell_id))
|
||||
{
|
||||
if(!IsInWorld() || disabled) // at spells loading, no output, but allow save
|
||||
if (!IsInWorld() || disabled) // at spells loading, no output, but allow save
|
||||
addSpell(prev_spell,active,true,true,disabled);
|
||||
else // at normal learning
|
||||
learnSpell(prev_spell,true);
|
||||
@@ -3141,21 +3142,23 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
newspell->disabled = disabled;
|
||||
|
||||
// replace spells in action bars and spellbook to bigger rank if only one spell rank must be accessible
|
||||
if(newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
if (newspell->active && !newspell->disabled && !SpellMgr::canStackSpellRanks(spellInfo) && spellmgr.GetSpellRank(spellInfo->Id) != 0)
|
||||
{
|
||||
for (PlayerSpellMap::iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2 )
|
||||
{
|
||||
if(itr2->second->state == PLAYERSPELL_REMOVED) continue;
|
||||
if (itr2->second->state == PLAYERSPELL_REMOVED)
|
||||
continue;
|
||||
SpellEntry const *i_spellInfo = sSpellStore.LookupEntry(itr2->first);
|
||||
if(!i_spellInfo) continue;
|
||||
if (!i_spellInfo)
|
||||
continue;
|
||||
|
||||
if( spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first) )
|
||||
if (spellmgr.IsRankSpellDueToSpell(spellInfo,itr2->first))
|
||||
{
|
||||
if(itr2->second->active)
|
||||
if (itr2->second->active)
|
||||
{
|
||||
if(spellmgr.IsHighRankOfSpell(spell_id,itr2->first))
|
||||
if (spellmgr.IsHighRankOfSpell(spell_id,itr2->first))
|
||||
{
|
||||
if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
|
||||
if (IsInWorld()) // not send spell (re-/over-)learn packets at loading
|
||||
{
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
||||
data << uint32(itr2->first);
|
||||
@@ -3169,19 +3172,19 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
itr2->second->state = PLAYERSPELL_CHANGED;
|
||||
superceded_old = true; // new spell replace old in action bars and spell book.
|
||||
}
|
||||
else if(spellmgr.IsHighRankOfSpell(itr2->first,spell_id))
|
||||
else if (spellmgr.IsHighRankOfSpell(itr2->first, spell_id))
|
||||
{
|
||||
if(IsInWorld()) // not send spell (re-/over-)learn packets at loading
|
||||
if (IsInWorld()) // not send spell (re-/over-)learn packets at loading
|
||||
{
|
||||
WorldPacket data(SMSG_SUPERCEDED_SPELL, 4 + 4);
|
||||
data << uint32(spell_id);
|
||||
data << uint32(itr2->first);
|
||||
GetSession()->SendPacket( &data );
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
// mark new spell as disable (not learned yet for client and will not learned)
|
||||
newspell->active = false;
|
||||
if(newspell->state != PLAYERSPELL_NEW)
|
||||
if (newspell->state != PLAYERSPELL_NEW)
|
||||
newspell->state = PLAYERSPELL_CHANGED;
|
||||
}
|
||||
}
|
||||
@@ -3223,7 +3226,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
|
||||
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
|
||||
{
|
||||
if(spellmgr.IsPrimaryProfessionFirstRankSpell(spell_id))
|
||||
if (spellmgr.IsPrimaryProfessionFirstRankSpell(spell_id))
|
||||
SetFreePrimaryProfessions(freeProfs-1);
|
||||
}
|
||||
|
||||
@@ -3247,7 +3250,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
if (skill_max_value < new_skill_max_value)
|
||||
skill_max_value = new_skill_max_value;
|
||||
|
||||
SetSkill(spellLearnSkill->skill,skill_value,skill_max_value);
|
||||
SetSkill(spellLearnSkill->skill, skill_value, skill_max_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3265,16 +3268,16 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
// lockpicking/runeforging special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL
|
||||
((pSkill->id==SKILL_LOCKPICKING || pSkill->id==SKILL_RUNEFORGING) && _spell_idx->second->max_value==0))
|
||||
{
|
||||
switch(GetSkillRangeType(pSkill,_spell_idx->second->racemask!=0))
|
||||
switch (GetSkillRangeType(pSkill,_spell_idx->second->racemask!=0))
|
||||
{
|
||||
case SKILL_RANGE_LANGUAGE:
|
||||
SetSkill(pSkill->id, 300, 300 );
|
||||
SetSkill(pSkill->id, 300, 300);
|
||||
break;
|
||||
case SKILL_RANGE_LEVEL:
|
||||
SetSkill(pSkill->id, 1, GetMaxSkillValueForLevel() );
|
||||
SetSkill(pSkill->id, 1, GetMaxSkillValueForLevel());
|
||||
break;
|
||||
case SKILL_RANGE_MONO:
|
||||
SetSkill(pSkill->id, 1, 1 );
|
||||
SetSkill(pSkill->id, 1, 1);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -3291,9 +3294,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
||||
if (!itr2->second.autoLearned)
|
||||
{
|
||||
if (!IsInWorld() || !itr2->second.active) // at spells loading, no output, but allow save
|
||||
addSpell(itr2->second.spell,itr2->second.active,true,true,false);
|
||||
addSpell(itr2->second.spell, itr2->second.active, true, true, false);
|
||||
else // at normal learning
|
||||
learnSpell(itr2->second.spell,true);
|
||||
learnSpell(itr2->second.spell, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3783,17 +3786,12 @@ bool Player::resetTalents(bool no_cost)
|
||||
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
for (PlayerTalentMap::iterator itr = m_talents[m_activeSpec]->begin(); itr != m_talents[m_activeSpec]->end(); ++itr)
|
||||
{
|
||||
removeSpell(itr->first, !IsPassiveSpell(itr->first), false);
|
||||
itr->second->state = PLAYERSPELL_REMOVED;
|
||||
}
|
||||
*/
|
||||
|
||||
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
|
||||
{
|
||||
PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
|
||||
// skip non-existant talent ranks
|
||||
if (talentInfo->RankID[rank] == 0)
|
||||
continue;
|
||||
// remove all talent related spells from the PlayerSpellMap
|
||||
for (PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end(); ++itr)
|
||||
{
|
||||
// remove learned spells (all ranks)
|
||||
@@ -3801,12 +3799,14 @@ bool Player::resetTalents(bool no_cost)
|
||||
|
||||
// unlearn if first rank is talent or learned by talent
|
||||
if (itrFirstId == talentInfo->RankID[rank])
|
||||
removeSpell(itr->first, true, false);
|
||||
removeSpell(itr->first, true, false); // disable the talent, delete it at the next _SaveSpells() call
|
||||
else if (spellmgr.IsSpellLearnToSpell(talentInfo->RankID[rank], itrFirstId))
|
||||
removeSpell(itr->first, true, true);
|
||||
removeSpell(itr->first, true, true); // disable the talent, delete it at the next _SaveSpells() call
|
||||
}
|
||||
// if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
|
||||
PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
|
||||
if (plrTalent != m_talents[m_activeSpec]->end())
|
||||
plrTalent->second->state = PLAYERSPELL_REMOVED; // mark the talent in the talent map as removed
|
||||
plrTalent->second->state = PLAYERSPELL_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3848,7 +3848,7 @@ Mail* Player::GetMail(uint32 id)
|
||||
|
||||
void Player::_SetCreateBits(UpdateMask *updateMask, Player *target) const
|
||||
{
|
||||
if(target == this)
|
||||
if (target == this)
|
||||
Object::_SetCreateBits(updateMask, target);
|
||||
else
|
||||
{
|
||||
@@ -3860,7 +3860,7 @@ void Player::_SetCreateBits(UpdateMask *updateMask, Player *target) const
|
||||
|
||||
void Player::_SetUpdateBits(UpdateMask *updateMask, Player *target) const
|
||||
{
|
||||
if(target == this)
|
||||
if (target == this)
|
||||
Object::_SetUpdateBits(updateMask, target);
|
||||
else
|
||||
{
|
||||
@@ -21984,39 +21984,45 @@ void Player::ActivateSpec(uint8 spec)
|
||||
//RemoveAllAuras(this->GetGUID(), NULL, false, true); // removes too many auras
|
||||
//ExitVehicle(); // should be impossible to switch specs from inside a vehicle..
|
||||
|
||||
// find class talent tabs (all players have 3 talent tabs)
|
||||
uint32 const *talentTabIds = GetTalentTabPages(getClass());
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||
{
|
||||
uint32 talentTabId = talentTabIds[i];
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(i);
|
||||
|
||||
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
|
||||
if (!talentInfo)
|
||||
continue;
|
||||
|
||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
|
||||
|
||||
if (!talentTabInfo)
|
||||
continue;
|
||||
|
||||
// unlearn only talents for character class
|
||||
// some spell learned by one class as normal spells or know at creation but another class learn it as talent,
|
||||
// to prevent unexpected lost normal learned spell skip another class talents
|
||||
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
|
||||
continue;
|
||||
|
||||
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
|
||||
{
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(talentId);
|
||||
if (!talentInfo)
|
||||
// skip non-existant talent ranks
|
||||
if (talentInfo->RankID[rank] == 0)
|
||||
continue;
|
||||
|
||||
// skip another tab talents
|
||||
if (talentInfo->TalentTab != talentTabId)
|
||||
continue;
|
||||
|
||||
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
|
||||
// remove all talent related spells from the PlayerSpellMap
|
||||
for (PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end(); ++itr)
|
||||
{
|
||||
//PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
|
||||
for (PlayerSpellMap::iterator itr = GetSpellMap().begin(); itr != GetSpellMap().end(); ++itr)
|
||||
{
|
||||
// remove learned spells (all ranks)
|
||||
uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first);
|
||||
// remove learned spells (all ranks)
|
||||
uint32 itrFirstId = spellmgr.GetFirstSpellInChain(itr->first);
|
||||
|
||||
// unlearn if first rank is talent or learned by talent
|
||||
if (itrFirstId == talentInfo->RankID[rank])
|
||||
removeSpell(itr->first, true, false);
|
||||
else if (spellmgr.IsSpellLearnToSpell(talentInfo->RankID[rank], itrFirstId))
|
||||
removeSpell(itr->first, true, true);
|
||||
}
|
||||
//plrTalent->second->state = PLAYERSPELL_REMOVED; // mark the talent in the talent map as removed
|
||||
// unlearn if first rank is talent or learned by talent
|
||||
if (itrFirstId == talentInfo->RankID[rank])
|
||||
removeSpell(itr->first, true, false); // disable the talent, delete it at the next _SaveSpells() call
|
||||
else if (spellmgr.IsSpellLearnToSpell(talentInfo->RankID[rank], itrFirstId))
|
||||
removeSpell(itr->first, true, true); // disable the talent, delete it at the next _SaveSpells() call
|
||||
}
|
||||
// if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
|
||||
//PlayerTalentMap::iterator plrTalent = m_talents[m_activeSpec]->find(talentInfo->RankID[rank]);
|
||||
//if (plrTalent != m_talents[m_activeSpec]->end())
|
||||
// plrTalent->second->state = PLAYERSPELL_REMOVED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22030,28 +22036,33 @@ void Player::ActivateSpec(uint8 spec)
|
||||
SetActiveSpec(spec);
|
||||
uint32 spentTalents = 0;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
|
||||
{
|
||||
uint32 talentTabId = talentTabIds[i];
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(talentId);
|
||||
|
||||
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
|
||||
if (!talentInfo)
|
||||
continue;
|
||||
|
||||
TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
|
||||
|
||||
if (!talentTabInfo)
|
||||
continue;
|
||||
|
||||
// learn only talents for character class
|
||||
if ((getClassMask() & talentTabInfo->ClassMask) == 0)
|
||||
continue;
|
||||
|
||||
// learn highest talent rank that exists in newly activated spec
|
||||
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
|
||||
{
|
||||
TalentEntry const *talentInfo = sTalentStore.LookupEntry(talentId);
|
||||
if (!talentInfo)
|
||||
// skip non-existant talent ranks
|
||||
if (talentInfo->RankID[rank] == 0)
|
||||
continue;
|
||||
|
||||
// skip another tab talents
|
||||
if (talentInfo->TalentTab != talentTabId)
|
||||
continue;
|
||||
|
||||
// learn highest talent rank that exists in newly activated spec
|
||||
for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
|
||||
// if the talent can be found in the newly activated PlayerTalentMap
|
||||
if (HasTalent(talentInfo->RankID[rank], m_activeSpec))
|
||||
{
|
||||
if (talentInfo->RankID[rank] && HasTalent(talentInfo->RankID[rank], m_activeSpec))
|
||||
{
|
||||
learnSpell(talentInfo->RankID[rank], false);
|
||||
spentTalents += (rank + 1);
|
||||
}
|
||||
learnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap
|
||||
spentTalents += (rank + 1); // increment the spentTalents count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user