diff options
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 35 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/StatSystem.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/SpellMgr.cpp | 57 |
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)); } |