diff --git a/sql/mangos.sql b/sql/mangos.sql index 5160521ff..4ea54c396 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `cache_id` int(10) default '0', - `required_12179_01_mangos_player_levelstats` bit(1) default NULL + `required_12180_01_mangos_spell_learn_spell` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -23299,7 +23299,17 @@ INSERT INTO `spell_learn_spell` VALUES (53428,53341,1), (53428,53343,1), (56815,56816,0), -(58984,21009,1); +(58984,21009,1), +(86467,86473,1), +(87491,86470,1), +(87492,86471,1), +(87493,86472,1), +(87494,86474,1), +(87495,86475,1), +(87496,86476,1), +(87497,86477,1), +(87498,86478,1), +(87500,86479,1); /*!40000 ALTER TABLE `spell_learn_spell` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/12180_01_mangos_spell_learn_spell.sql b/sql/updates/12180_01_mangos_spell_learn_spell.sql new file mode 100644 index 000000000..da0101b1c --- /dev/null +++ b/sql/updates/12180_01_mangos_spell_learn_spell.sql @@ -0,0 +1,29 @@ +ALTER TABLE db_version CHANGE COLUMN required_12179_01_mangos_player_levelstats required_12180_01_mangos_spell_learn_spell bit; + +ALTER TABLE `spell_learn_spell` MODIFY COLUMN `entry` mediumint(8) unsigned NOT NULL DEFAULT '0'; +ALTER TABLE `spell_learn_spell` MODIFY COLUMN `SpellID` mediumint(8) unsigned NOT NULL DEFAULT '0'; + +DELETE FROM `spell_learn_spell` WHERE `entry` IN +(87492, 87491, 87493, 86467, 87494, 87495, 87496, 87497, 87498, 87500); + +INSERT INTO `spell_learn_spell` (`entry`, `SpellID`, `Active`) VALUES +-- Death Knight +(87492, 86471, 1), +-- Druid +(87491, 86470, 1), +-- Hunter +(87493, 86472, 1), +-- Mage +(86467, 86473, 1), +-- Paladin +(87494, 86474, 1), +-- Priest +(87495, 86475, 1), +-- Rogue +(87496, 86476, 1), +-- Shaman +(87497, 86477, 1), +-- Warlock +(87498, 86478, 1), +-- Warrior +(87500, 86479, 1); \ No newline at end of file diff --git a/src/game/DBCStores.cpp b/src/game/DBCStores.cpp index 47814717a..45dcf7c84 100644 --- a/src/game/DBCStores.cpp +++ b/src/game/DBCStores.cpp @@ -205,8 +205,9 @@ DBCStorage sTalentStore(TalentEntryfmt); TalentSpellPosMap sTalentSpellPosMap; DBCStorage sTalentTabStore(TalentTabEntryfmt); DBCStorage sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt); -typedef std::map > TalentTreePrimarySpellsMap; -TalentTreePrimarySpellsMap sTalentTreePrimarySpellsMap; +typedef std::map > TalentTreeSpellsMap; +TalentTreeSpellsMap sTalentTreeMasterySpellsMap; +TalentTreeSpellsMap sTalentTreePrimarySpellsMap; // store absolute bit position for first rank for talent inspect static uint32 sTalentTabPages[MAX_CLASSES][3]; @@ -676,6 +677,11 @@ void LoadDBCStores(const std::string& dataPath) if(!talentTabInfo) continue; + for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i) + if (uint32 spellid = talentTabInfo->masterySpells[i]) + if (sSpellStore.LookupEntry(spellid)) + sTalentTreeMasterySpellsMap[talentTabId].push_back(spellid); + // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0) continue; @@ -690,7 +696,8 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc"); for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i) if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i)) - sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId); + if (sSpellStore.LookupEntry(talentSpell->SpellId)) + sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId); sTalentTreePrimarySpellsStore.Clear(); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTaxiNodesStore, dbcPath,"TaxiNodes.dbc"); @@ -1062,9 +1069,18 @@ uint32 const* GetTalentTabPages(uint32 cls) return sTalentTabPages[cls]; } +std::vector const* GetTalentTreeMasterySpells(uint32 talentTree) +{ + TalentTreeSpellsMap::const_iterator itr = sTalentTreeMasterySpellsMap.find(talentTree); + if (itr == sTalentTreeMasterySpellsMap.end()) + return NULL; + + return &itr->second; +} + std::vector const* GetTalentTreePrimarySpells(uint32 talentTree) { - TalentTreePrimarySpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree); + TalentTreeSpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree); if (itr == sTalentTreePrimarySpellsMap.end()) return NULL; diff --git a/src/game/DBCStores.h b/src/game/DBCStores.h index 488d25a2c..fdc83baaf 100644 --- a/src/game/DBCStores.h +++ b/src/game/DBCStores.h @@ -89,6 +89,7 @@ inline Difficulty GetPrevDifficulty(Difficulty diff, bool isRaid) } uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); +std::vector const* GetTalentTreeMasterySpells(uint32 talentTree); std::vector const* GetTalentTreePrimarySpells(uint32 talentTree); bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f); diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index a96ec9452..699ee9e05 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -2148,6 +2148,8 @@ struct TalentEntry //uint64 allowForPet; // 17 m_categoryMask its a 64 bit mask for pet 1< const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); - if (specSpells) + if (std::vector const* specSpells = GetTalentTreeMasterySpells(GetTalentTabPages(getClass())[i])) + for (size_t i = 0; i < specSpells->size(); ++i) + removeSpell(specSpells->at(i), true); + + if (std::vector const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i])) for (size_t i = 0; i < specSpells->size(); ++i) removeSpell(specSpells->at(i), true); } - m_talentsPrimaryTree[m_activeSpec] = 0; + for (uint8 spec = 0; spec < MAX_TALENT_SPEC_COUNT; ++spec) + { + if (!all_specs && spec != m_activeSpec) + continue; + + m_talentsPrimaryTree[spec] = 0; + } // for not current spec just mark removed all saved to DB case and drop not saved if (all_specs) @@ -15767,7 +15776,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder) break; uint32 talentTree = atol(talentTrees[i].c_str()); - if (sTalentTabStore.LookupEntry(talentTree)) + if (!talentTree || sTalentTabStore.LookupEntry(talentTree)) m_talentsPrimaryTree[i] = talentTree; else if (i == m_activeSpec) SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents @@ -22173,8 +22182,12 @@ bool Player::LearnTalent(uint32 talentId, uint32 talentRank) if (!m_talentsPrimaryTree[m_activeSpec]) { m_talentsPrimaryTree[m_activeSpec] = talentInfo->TalentTab; - std::vector const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab); - if (specSpells) + if (std::vector const* specSpells = GetTalentTreeMasterySpells(talentInfo->TalentTab)) + if (HasAuraType(SPELL_AURA_MASTERY)) + for (size_t i = 0; i < specSpells->size(); ++i) + learnSpell(specSpells->at(i), false); + + if (std::vector const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab)) for (size_t i = 0; i < specSpells->size(); ++i) learnSpell(specSpells->at(i), false); } @@ -22747,8 +22760,11 @@ void Player::ActivateSpec(uint8 specNum) // Remove spec specific spells for (uint32 i = 0; i < MAX_TALENT_TABS; ++i) { - std::vector const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); - if (specSpells) + if (std::vector const* specSpells = GetTalentTreeMasterySpells(GetTalentTabPages(getClass())[i])) + for (size_t i = 0; i < specSpells->size(); ++i) + removeSpell(specSpells->at(i), true); + + if (std::vector const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i])) for (size_t i = 0; i < specSpells->size(); ++i) removeSpell(specSpells->at(i), true); } @@ -22855,8 +22871,12 @@ void Player::ActivateSpec(uint8 specNum) ResummonPetTemporaryUnSummonedIfAny(); - std::vector const* specSpells = GetTalentTreePrimarySpells(m_talentsPrimaryTree[m_activeSpec]); - if (specSpells) + if (std::vector const* specSpells = GetTalentTreeMasterySpells(m_talentsPrimaryTree[m_activeSpec])) + if (HasAuraType(SPELL_AURA_MASTERY)) + for (size_t i = 0; i < specSpells->size(); ++i) + learnSpell(specSpells->at(i), false); + + if (std::vector const* specSpells = GetTalentTreePrimarySpells(m_talentsPrimaryTree[m_activeSpec])) for (size_t i = 0; i < specSpells->size(); ++i) learnSpell(specSpells->at(i), false); @@ -22870,7 +22890,7 @@ void Player::ActivateSpec(uint8 specNum) SetPower(pw, 0); - if (!sTalentTabStore.LookupEntry(m_talentsPrimaryTree[m_activeSpec])) + if (m_talentsPrimaryTree[m_activeSpec] && !sTalentTabStore.LookupEntry(m_talentsPrimaryTree[m_activeSpec])) resetTalents(true); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 988c3b036..4f856cb63 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12179" + #define REVISION_NR "12180" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index c79e5a162..726dc0754 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #define REVISION_DB_CHARACTERS "required_12161_01_characters_characters" - #define REVISION_DB_MANGOS "required_12179_01_mangos_player_levelstats" + #define REVISION_DB_MANGOS "required_12180_01_mangos_spell_learn_spell" #define REVISION_DB_REALMD "required_12112_01_realmd_account_access" #endif // __REVISION_SQL_H__