[12180] Fix bugs related to talent trees.

Implement mastery spells learn

Signed-off-by: Yaki Khadafi <elsoldollo@gmail.com>
This commit is contained in:
Yaki Khadafi 2012-09-04 17:01:11 +03:00 committed by Antz
parent 3cb9dd9eec
commit 092052608f
8 changed files with 98 additions and 20 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `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'; ) 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,53341,1),
(53428,53343,1), (53428,53343,1),
(56815,56816,0), (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 */; /*!40000 ALTER TABLE `spell_learn_spell` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;

View file

@ -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);

View file

@ -205,8 +205,9 @@ DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap; TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt); DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
DBCStorage <TalentTreePrimarySpellsEntry> sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt); DBCStorage <TalentTreePrimarySpellsEntry> sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt);
typedef std::map<uint32, std::vector<uint32> > TalentTreePrimarySpellsMap; typedef std::map<uint32, std::vector<uint32> > TalentTreeSpellsMap;
TalentTreePrimarySpellsMap sTalentTreePrimarySpellsMap; TalentTreeSpellsMap sTalentTreeMasterySpellsMap;
TalentTreeSpellsMap sTalentTreePrimarySpellsMap;
// store absolute bit position for first rank for talent inspect // store absolute bit position for first rank for talent inspect
static uint32 sTalentTabPages[MAX_CLASSES][3]; static uint32 sTalentTabPages[MAX_CLASSES][3];
@ -676,6 +677,11 @@ void LoadDBCStores(const std::string& dataPath)
if(!talentTabInfo) if(!talentTabInfo)
continue; 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 // prevent memory corruption; otherwise cls will become 12 below
if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0) if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE)==0)
continue; continue;
@ -690,6 +696,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files, sTalentTreePrimarySpellsStore, dbcPath, "TalentTreePrimarySpells.dbc");
for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i) for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i)
if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i)) if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i))
if (sSpellStore.LookupEntry(talentSpell->SpellId))
sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId); sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId);
sTalentTreePrimarySpellsStore.Clear(); sTalentTreePrimarySpellsStore.Clear();
@ -1062,9 +1069,18 @@ uint32 const* GetTalentTabPages(uint32 cls)
return sTalentTabPages[cls]; return sTalentTabPages[cls];
} }
std::vector<uint32> const* GetTalentTreeMasterySpells(uint32 talentTree)
{
TalentTreeSpellsMap::const_iterator itr = sTalentTreeMasterySpellsMap.find(talentTree);
if (itr == sTalentTreeMasterySpellsMap.end())
return NULL;
return &itr->second;
}
std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree) std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree)
{ {
TalentTreePrimarySpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree); TalentTreeSpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree);
if (itr == sTalentTreePrimarySpellsMap.end()) if (itr == sTalentTreePrimarySpellsMap.end())
return NULL; return NULL;

View file

@ -89,6 +89,7 @@ inline Difficulty GetPrevDifficulty(Difficulty diff, bool isRaid)
} }
uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls); uint32 const* /*[3]*/ GetTalentTabPages(uint32 cls);
std::vector<uint32> const* GetTalentTreeMasterySpells(uint32 talentTree);
std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree); std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree);
bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f); bool IsPointInAreaTriggerZone(AreaTriggerEntry const* atEntry, uint32 mapid, float x, float y, float z, float delta = 0.0f);

View file

@ -2148,6 +2148,8 @@ struct TalentEntry
//uint64 allowForPet; // 17 m_categoryMask its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc //uint64 allowForPet; // 17 m_categoryMask its a 64 bit mask for pet 1<<m_categoryEnumID in CreatureFamily.dbc
}; };
#define MAX_MASTERY_SPELLS 2
struct TalentTabEntry struct TalentTabEntry
{ {
uint32 TalentTabID; // 0 m_ID uint32 TalentTabID; // 0 m_ID
@ -2159,7 +2161,7 @@ struct TalentTabEntry
//char* internalname; // 6 m_backgroundFile //char* internalname; // 6 m_backgroundFile
//char* description; // 7 //char* description; // 7
//uint32 rolesMask; // 8 4.0.0 //uint32 rolesMask; // 8 4.0.0
uint32 masterySpells[2]; // 9-10 passive mastery bonus spells uint32 masterySpells[MAX_MASTERY_SPELLS]; // 9-10 passive mastery bonus spells
}; };
struct TalentTreePrimarySpellsEntry struct TalentTreePrimarySpellsEntry

View file

@ -3851,13 +3851,22 @@ bool Player::resetTalents(bool no_cost, bool all_specs)
// Remove spec specific spells // Remove spec specific spells
for (uint32 i = 0; i < MAX_TALENT_TABS; ++i) for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
{ {
std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); if (std::vector<uint32> const* specSpells = GetTalentTreeMasterySpells(GetTalentTabPages(getClass())[i]))
if (specSpells) for (size_t i = 0; i < specSpells->size(); ++i)
removeSpell(specSpells->at(i), true);
if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]))
for (size_t i = 0; i < specSpells->size(); ++i) for (size_t i = 0; i < specSpells->size(); ++i)
removeSpell(specSpells->at(i), true); 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 // for not current spec just mark removed all saved to DB case and drop not saved
if (all_specs) if (all_specs)
@ -15767,7 +15776,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SqlQueryHolder* holder)
break; break;
uint32 talentTree = atol(talentTrees[i].c_str()); uint32 talentTree = atol(talentTrees[i].c_str());
if (sTalentTabStore.LookupEntry(talentTree)) if (!talentTree || sTalentTabStore.LookupEntry(talentTree))
m_talentsPrimaryTree[i] = talentTree; m_talentsPrimaryTree[i] = talentTree;
else if (i == m_activeSpec) else if (i == m_activeSpec)
SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents 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]) if (!m_talentsPrimaryTree[m_activeSpec])
{ {
m_talentsPrimaryTree[m_activeSpec] = talentInfo->TalentTab; m_talentsPrimaryTree[m_activeSpec] = talentInfo->TalentTab;
std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab); if (std::vector<uint32> const* specSpells = GetTalentTreeMasterySpells(talentInfo->TalentTab))
if (specSpells) if (HasAuraType(SPELL_AURA_MASTERY))
for (size_t i = 0; i < specSpells->size(); ++i)
learnSpell(specSpells->at(i), false);
if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab))
for (size_t i = 0; i < specSpells->size(); ++i) for (size_t i = 0; i < specSpells->size(); ++i)
learnSpell(specSpells->at(i), false); learnSpell(specSpells->at(i), false);
} }
@ -22747,8 +22760,11 @@ void Player::ActivateSpec(uint8 specNum)
// Remove spec specific spells // Remove spec specific spells
for (uint32 i = 0; i < MAX_TALENT_TABS; ++i) for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
{ {
std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]); if (std::vector<uint32> const* specSpells = GetTalentTreeMasterySpells(GetTalentTabPages(getClass())[i]))
if (specSpells) for (size_t i = 0; i < specSpells->size(); ++i)
removeSpell(specSpells->at(i), true);
if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]))
for (size_t i = 0; i < specSpells->size(); ++i) for (size_t i = 0; i < specSpells->size(); ++i)
removeSpell(specSpells->at(i), true); removeSpell(specSpells->at(i), true);
} }
@ -22855,8 +22871,12 @@ void Player::ActivateSpec(uint8 specNum)
ResummonPetTemporaryUnSummonedIfAny(); ResummonPetTemporaryUnSummonedIfAny();
std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(m_talentsPrimaryTree[m_activeSpec]); if (std::vector<uint32> const* specSpells = GetTalentTreeMasterySpells(m_talentsPrimaryTree[m_activeSpec]))
if (specSpells) if (HasAuraType(SPELL_AURA_MASTERY))
for (size_t i = 0; i < specSpells->size(); ++i)
learnSpell(specSpells->at(i), false);
if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(m_talentsPrimaryTree[m_activeSpec]))
for (size_t i = 0; i < specSpells->size(); ++i) for (size_t i = 0; i < specSpells->size(); ++i)
learnSpell(specSpells->at(i), false); learnSpell(specSpells->at(i), false);
@ -22870,7 +22890,7 @@ void Player::ActivateSpec(uint8 specNum)
SetPower(pw, 0); SetPower(pw, 0);
if (!sTalentTabStore.LookupEntry(m_talentsPrimaryTree[m_activeSpec])) if (m_talentsPrimaryTree[m_activeSpec] && !sTalentTabStore.LookupEntry(m_talentsPrimaryTree[m_activeSpec]))
resetTalents(true); resetTalents(true);
} }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "12179" #define REVISION_NR "12180"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_12161_01_characters_characters" #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" #define REVISION_DB_REALMD "required_12112_01_realmd_account_access"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__