aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Player/Player.cpp35
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp6
-rw-r--r--src/server/game/Spells/SpellMgr.cpp57
4 files changed, 93 insertions, 7 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 901572d80b2..183be944b31 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -28049,12 +28049,25 @@ Pet* Player::SummonPet(uint32 entry, Optional<PetSaveMode> slot, float x, float
return pet;
}
+std::array<uint32, MAX_CLASS_ID + 1> MasterySpells =
+{
+ 0,
+ 87500, // Warrior
+ 87494, // Paladin
+ 87493, // Hunter
+ 87496, // Rogue
+ 87495, // Priest
+ 87492, // Death Knight
+ 87497, // Shaman
+ 86467, // Mage
+ 87498, // Warlock
+ 0,
+ 87491 // Druid
+};
+
bool Player::CanUseMastery() const
{
- if (ChrSpecializationEntry const* chrSpec = GetPrimarySpecializationEntry())
- return HasSpell(chrSpec->MasterySpellID[0]) || HasSpell(chrSpec->MasterySpellID[1]);
-
- return false;
+ return HasSpell(MasterySpells[GetClass()]);
}
void Player::ValidateMovementInfo(MovementInfo* mi)
@@ -28451,13 +28464,27 @@ void Player::SetActiveTalentGroup(uint8 group, bool withUpdate /*= true*/, bool
void Player::SetPrimaryTalentTree(uint32 talentTabId, bool withUpdate /*= false*/)
{
if (!talentTabId || GetPrimaryTalentTree() != talentTabId)
+ {
UnlearnTalentTreePrimarySpells();
+ if (TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree()))
+ for (uint32 spellId : talentTab->MasterySpellID)
+ RemoveSpell(spellId, true);
+ }
+
_talentGroups[_activeTalentGroup].PrimaryTalentTabID = talentTabId;
if (talentTabId)
+ {
LearnTalentTreePrimarySpells();
+ if (CanUseMastery())
+ if (TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree()))
+ for (uint32 spellId : talentTab->MasterySpellID)
+ if (sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))
+ LearnSpell(spellId, true);
+ }
+
if (withUpdate)
SendTalentsInfoData();
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 03ec4aa199d..42d287e1b77 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -201,6 +201,8 @@ struct PlayerSpell
Optional<int32> TraitDefinitionId;
};
+extern std::array<uint32, MAX_CLASS_ID + 1> MasterySpells;
+
struct StoredAuraTeleportLocation
{
WorldLocation Loc;
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index 62247bfa98b..8226ac7c00d 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -657,11 +657,11 @@ void Player::UpdateMastery()
value += GetRatingBonusValue(CR_MASTERY);
SetUpdateFieldValue(m_values.ModifyValue(&Player::m_activePlayerData).ModifyValue(&UF::ActivePlayerData::Mastery), value);
- ChrSpecializationEntry const* chrSpec = GetPrimarySpecializationEntry();
- if (!chrSpec)
+ TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree());
+ if (!talentTab)
return;
- for (int32 masterySpellId : chrSpec->MasterySpellID)
+ for (int32 masterySpellId : talentTab->MasterySpellID)
{
if (Aura* aura = GetAura(masterySpellId))
{
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index fa13dadd5a6..5abf6b02ef9 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -1197,6 +1197,63 @@ void SpellMgr::LoadSpellLearnSpells()
++dbc_count;
}
+ uint32 mastery_count = 0;
+ for (TalentTabEntry const* talentTab : sTalentTabStore)
+ {
+ for (uint32 c = CLASS_WARRIOR; c < MAX_CLASSES; ++c)
+ {
+ if (!(talentTab->ClassMask & (1 << (c - 1))))
+ continue;
+
+ uint32 masteryMainSpell = MasterySpells[c];
+
+ for (uint32 mastery : talentTab->MasterySpellID)
+ {
+ if (!mastery)
+ continue;
+
+ SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(masteryMainSpell);
+ bool found = false;
+ for (SpellLearnSpellMap::const_iterator itr = db_node_bounds.first; itr != db_node_bounds.second; ++itr)
+ {
+ if (itr->second.Spell == mastery)
+ {
+ TC_LOG_ERROR("sql.sql", "Found redundant record (entry: %u, SpellID: %u) in `spell_learn_spell`, spell added automatically as mastery learned spell from ChrSpecialization.dbc", masteryMainSpell, mastery);
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ // Check if it is already found in Spell.dbc, ignore silently if yes
+ SpellLearnSpellMapBounds dbc_node_bounds = GetSpellLearnSpellMapBounds(masteryMainSpell);
+ found = false;
+ for (SpellLearnSpellMap::const_iterator itr = dbc_node_bounds.first; itr != dbc_node_bounds.second; ++itr)
+ {
+ if (itr->second.Spell == mastery)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+
+ SpellLearnSpellNode masteryNode;
+ masteryNode.Spell = mastery;
+ masteryNode.OverridesSpell = 0;
+ masteryNode.Active = true;
+ masteryNode.AutoLearned = false;
+
+ mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(masteryMainSpell, masteryNode));
+ ++mastery_count;
+ }
+ }
+ }
+
TC_LOG_INFO("server.loading", ">> Loaded {} spell learn spells, {} found in Spell.dbc in {} ms", count, dbc_count, GetMSTimeDiffToNow(oldMSTime));
}