aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIntel <chemicstry@gmail.com>2014-11-10 21:09:18 +0200
committerIntel <chemicstry@gmail.com>2014-11-10 21:09:18 +0200
commit24850994b4fc1b285e84f2f44f2278bf3a091900 (patch)
tree774312cc1e1918f7878947a7024e13827eb6eabd /src
parente90ef4fa24a1da7f4d7433a1522e5cb43ef68d29 (diff)
Core/Talents: Update talent system, remove talent points
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Battlegrounds/ArenaScore.h3
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp3
-rw-r--r--src/server/game/Battlegrounds/Battleground.h2
-rw-r--r--src/server/game/Battlegrounds/BattlegroundScore.h3
-rw-r--r--src/server/game/Chat/Chat.cpp9
-rw-r--r--src/server/game/Chat/ChatLink.cpp4
-rw-r--r--src/server/game/DataStores/DB2Structure.h2
-rw-r--r--src/server/game/DataStores/DBCStores.cpp75
-rw-r--r--src/server/game/DataStores/DBCStores.h16
-rw-r--r--src/server/game/DataStores/DBCStructure.h109
-rw-r--r--src/server/game/DataStores/DBCfmt.h2
-rw-r--r--src/server/game/Entities/Pet/Pet.cpp47
-rw-r--r--src/server/game/Entities/Player/Player.cpp609
-rw-r--r--src/server/game/Entities/Player/Player.h94
-rw-r--r--src/server/game/Entities/Totem/Totem.cpp4
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp8
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp20
-rw-r--r--src/server/game/Handlers/PetHandler.cpp6
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp6
-rw-r--r--src/server/game/Spells/SpellEffects.cpp2
-rw-r--r--src/server/game/Spells/SpellInfo.cpp3
-rw-r--r--src/server/game/Spells/SpellMgr.cpp17
-rw-r--r--src/server/game/Tools/CharacterDatabaseCleaner.cpp4
-rw-r--r--src/server/scripts/Commands/cs_learn.cpp43
-rw-r--r--src/server/scripts/Commands/cs_list.cpp2
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp12
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp3
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp2
28 files changed, 313 insertions, 797 deletions
diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h
index a1847f546ea..b6b79405ab8 100644
--- a/src/server/game/Battlegrounds/ArenaScore.h
+++ b/src/server/game/Battlegrounds/ArenaScore.h
@@ -33,8 +33,9 @@ struct ArenaScore : public BattlegroundScore
void AppendToPacket(WorldPacket& data, ByteBuffer& content) final override
{
uint32 primaryTree = 0;
+ /* TODO: 6.x update to new talent system (and probably rewrite this packet)
if (Player* player = ObjectAccessor::FindPlayer(PlayerGuid))
- primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());
+ primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());*/
data.WriteBit(0); // Unk 1
data.WriteBit(0); // Unk 2
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index c021b731714..46c2e5739ab 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -1066,12 +1066,11 @@ void Battleground::AddPlayer(Player* player)
// score struct must be created in inherited class
uint32 team = player->GetBGTeam();
- int32 primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());
BattlegroundPlayer bp;
bp.OfflineRemoveTime = 0;
bp.Team = team;
- bp.PrimaryTree = primaryTree;
+ bp.ActiveSpec = player->GetActiveSpec();
// Add to list/maps
m_Players[player->GetGUID()] = bp;
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index aa0bb6fbb4c..5bd18977c3d 100644
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -160,7 +160,7 @@ struct BattlegroundPlayer
{
time_t OfflineRemoveTime; // for tracking and removing offline players from queue after 5 minutes
uint32 Team; // Player's team
- int32 PrimaryTree; // Player's primary tree
+ int32 ActiveSpec; // Player's active spec
};
struct BattlegroundObjectInfo
diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h
index 2bca2788c61..8d197869ed6 100644
--- a/src/server/game/Battlegrounds/BattlegroundScore.h
+++ b/src/server/game/Battlegrounds/BattlegroundScore.h
@@ -93,8 +93,9 @@ struct BattlegroundScore
virtual void AppendToPacket(WorldPacket& data, ByteBuffer& content)
{
uint32 primaryTree = 0;
+ /* TODO: 6.x update to new talent system (and probably rewrite this packet)
if (Player* player = ObjectAccessor::FindPlayer(PlayerGuid))
- primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());
+ primaryTree = player->GetPrimaryTalentTree(player->GetActiveSpec());*/
data.WriteBit(0); // Unk 1
data.WriteBit(0); // Unk 2
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index fce0fc99b4a..83c39349593 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -1013,14 +1013,7 @@ uint32 ChatHandler::extractSpellIdFromLink(char* text)
if (!talentEntry)
return 0;
- int32 rank = param1_str ? (uint32)atol(param1_str) : 0;
- if (rank >= MAX_TALENT_RANK)
- return 0;
-
- if (rank < 0)
- rank = 0;
-
- return talentEntry->RankID[rank];
+ return talentEntry->SpellID;
}
case SPELL_LINK_ENCHANT:
case SPELL_LINK_TRADE:
diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp
index e671713c643..eb99a19cf78 100644
--- a/src/server/game/Chat/ChatLink.cpp
+++ b/src/server/game/Chat/ChatLink.cpp
@@ -451,10 +451,10 @@ bool TalentChatLink::Initialize(std::istringstream& iss)
return false;
}
// Validate talent's spell
- _spell = sSpellMgr->GetSpellInfo(talentInfo->RankID[0]);
+ _spell = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
if (!_spell)
{
- TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid spell id %u in |trade command", iss.str().c_str(), talentInfo->RankID[0]);
+ TC_LOG_TRACE("chat.system", "ChatHandler::isValidChatMessage('%s'): got invalid spell id %u in |trade command", iss.str().c_str(), talentInfo->SpellID);
return false;
}
// Delimiter
diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h
index 02fcbc0898b..84967343120 100644
--- a/src/server/game/DataStores/DB2Structure.h
+++ b/src/server/game/DataStores/DB2Structure.h
@@ -191,7 +191,7 @@ struct SpellMiscEntry
uint32 CastingTimeIndex; // 15
uint32 DurationIndex; // 16
uint32 RangeIndex; // 17
- uint32 Speed; // 18
+ float Speed; // 18
uint32 SpellVisualID[2]; // 19-20
uint32 SpellIconID; // 21
uint32 ActiveIconID; // 22
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index d1cfa2c1720..598c2e5d5f3 100644
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -74,6 +74,8 @@ DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt);
DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt);
DBCStorage <ChrRacesEntry> sChrRacesStore(ChrRacesEntryfmt);
DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore(ChrClassesXPowerTypesfmt);
+DBCStorage <ChrSpecializationEntry> sChrSpecializationStore(ChrSpecializationEntryfmt);
+SpecializationSpellsBySpecStore sSpecializationSpellsBySpecStore;
DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore(CinematicSequencesEntryfmt);
DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore(CreatureDisplayInfofmt);
DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore(CreatureDisplayInfoExtrafmt);
@@ -188,6 +190,7 @@ DBCStorage <SkillTiersEntry> sSkillTiersStore(SkillTiersfmt);
DBCStorage <SoundEntriesEntry> sSoundEntriesStore(SoundEntriesfmt);
+DBCStorage <SpecializationSpellsEntry> sSpecializationSpellsStore(SpecializationSpellsEntryfmt);
DBCStorage <SpellItemEnchantmentEntry> sSpellItemEnchantmentStore(SpellItemEnchantmentfmt);
DBCStorage <SpellItemEnchantmentConditionEntry> sSpellItemEnchantmentConditionStore(SpellItemEnchantmentConditionfmt);
DBCStorage <SpellEntry> sSpellStore(SpellEntryfmt);
@@ -217,14 +220,7 @@ DBCStorage <SpellShapeshiftFormEntry> sSpellShapeshiftFormStore(SpellShapeshiftF
DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
-TalentSpellPosMap sTalentSpellPosMap;
-DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
-DBCStorage <TalentTreePrimarySpellsEntry> sTalentTreePrimarySpellsStore(TalentTreePrimarySpellsfmt);
-typedef std::map<uint32, std::vector<uint32> > TalentTreePrimarySpellsMap;
-TalentTreePrimarySpellsMap sTalentTreePrimarySpellsMap;
-
-// store absolute bit position for first rank for talent inspect
-static uint32 sTalentTabPages[MAX_CLASSES][3];
+TalentBySpellIDMap sTalentBySpellIDMap;
DBCStorage <TaxiNodesEntry> sTaxiNodesStore(TaxiNodesEntryfmt);
TaxiMask sTaxiNodesMask;
@@ -375,6 +371,8 @@ void LoadDBCStores(const std::string& dataPath)
PowersByClass[power->ClassID][power->PowerType] = index;
}
}
+
+ LoadDBC(availableDbcLocales, bad_dbc_files, sChrSpecializationStore, dbcPath, "ChrSpecialization.dbc");
LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc");//19116
LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc");//19116
@@ -529,10 +527,18 @@ void LoadDBCStores(const std::string& dataPath)
if (sSkillLineStore.LookupEntry(entry->SkillID))
SkillRaceClassInfoBySkill.emplace(entry->SkillID, entry);
- LoadDBC(availableDbcLocales, bad_dbc_files, sSkillTiersStore, dbcPath, "SkillTiers.dbc");//19116
- LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");//19116
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"/*, &CustomSpellEntryfmt, &CustomSpellEntryIndex*/);//19116
- LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath,"SpellCategories.dbc");//19116
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSkillTiersStore, dbcPath, "SkillTiers.dbc");
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc");//15595
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpecializationSpellsStore, dbcPath, "SpecializationSpells.dbc");
+ for (uint32 i = 1; i < sSpecializationSpellsStore.GetNumRows(); ++i)
+ {
+ SpecializationSpellsEntry const* specSpells = sSpecializationSpellsStore.LookupEntry(i);
+ if (!specSpells)
+ continue;
+ sSpecializationSpellsBySpecStore[specSpells->SpecID].insert(specSpells);
+ }
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc"/*, &CustomSpellEntryfmt, &CustomSpellEntryIndex*/);
+ LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath, "SpellCategories.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoryStore, dbcPath, "SpellCategory.dbc");
for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
{
@@ -634,19 +640,17 @@ void LoadDBCStores(const std::string& dataPath)
sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID);
}*/
- // create talent spells set
for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i)
{
TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
if (!talentInfo)
continue;
- for (int j = 0; j < MAX_TALENT_RANK; j++)
- if (talentInfo->RankID[j])
- sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j);
+ sTalentBySpellIDMap[talentInfo->SpellID] = talentInfo;
}
- LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc");//15595
+ // create talent spells set
+ /* TODO: 6.x update to new talent system
// prepare fast data access to bit pos of talent ranks for use at inspecting
{
@@ -672,8 +676,8 @@ void LoadDBCStores(const std::string& dataPath)
for (uint32 i = 0; i < sTalentTreePrimarySpellsStore.GetNumRows(); ++i)
if (TalentTreePrimarySpellsEntry const* talentSpell = sTalentTreePrimarySpellsStore.LookupEntry(i))
sTalentTreePrimarySpellsMap[talentSpell->TalentTree].push_back(talentSpell->SpellId);
- sTalentTreePrimarySpellsStore.Clear();
-
+ sTalentTreePrimarySpellsStore.Clear();*/
+
LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc");//15595
LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc");//15595
for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i)
@@ -851,23 +855,6 @@ char const* GetPetName(uint32 petfamily, uint32 /*dbclang*/)
return pet_family->Name_lang ? pet_family->Name_lang : NULL;
}
-TalentSpellPos const* GetTalentSpellPos(uint32 spellId)
-{
- TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId);
- if (itr == sTalentSpellPosMap.end())
- return NULL;
-
- return &itr->second;
-}
-
-uint32 GetTalentSpellCost(uint32 spellId)
-{
- if (TalentSpellPos const* pos = GetTalentSpellPos(spellId))
- return pos->rank+1;
-
- return 0;
-}
-
int32 GetAreaFlagByAreaID(uint32 area_id)
{
AreaFlagByAreaID::iterator i = sAreaFlagByAreaID.find(area_id);
@@ -1097,18 +1084,12 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB
return NULL;
}
-uint32 const* GetTalentTabPages(uint8 cls)
+TalentEntry const* GetTalentBySpellID(uint32 spellID)
{
- return sTalentTabPages[cls];
-}
-
-std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree)
-{
- TalentTreePrimarySpellsMap::const_iterator itr = sTalentTreePrimarySpellsMap.find(talentTree);
- if (itr == sTalentTreePrimarySpellsMap.end())
- return NULL;
-
- return &itr->second;
+ auto itr = sTalentBySpellIDMap.find(spellID);
+ if (itr != sTalentBySpellIDMap.end())
+ return itr->second;
+ return nullptr;
}
uint32 GetLiquidFlags(uint32 liquidType)
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index 53be6a0ebb9..bb75a5ed6b5 100644
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -29,8 +29,8 @@ typedef std::list<uint32> SimpleFactionsList;
SimpleFactionsList const* GetFactionTeamList(uint32 faction);
char const* GetPetName(uint32 petfamily, uint32 dbclang);
-uint32 GetTalentSpellCost(uint32 spellId);
-TalentSpellPos const* GetTalentSpellPos(uint32 spellId);
+
+TalentEntry const* GetTalentBySpellID(uint32 spellID);
int32 GetAreaFlagByAreaID(uint32 area_id); // -1 if not found
AreaTableEntry const* GetAreaEntryByAreaID(uint32 area_id);
@@ -70,9 +70,6 @@ typedef std::map<uint32/*pair32(map, diff)*/, MapDifficulty> MapDifficultyMap;
MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty);
MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty);
-uint32 const* /*[MAX_TALENT_TABS]*/ GetTalentTabPages(uint8 cls);
-std::vector<uint32> const* GetTalentTreePrimarySpells(uint32 talentTree);
-
uint32 GetLiquidFlags(uint32 liquidType);
PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level);
@@ -91,6 +88,10 @@ typedef std::unordered_multimap<uint32, SkillRaceClassInfoEntry const*> SkillRac
typedef std::pair<SkillRaceClassInfoMap::iterator, SkillRaceClassInfoMap::iterator> SkillRaceClassInfoBounds;
SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, uint8 class_);
+typedef std::set<SpecializationSpellsEntry const*> SpecializationSpellsBySpecEntry;
+typedef std::unordered_map<uint32, SpecializationSpellsBySpecEntry> SpecializationSpellsBySpecStore;
+typedef std::unordered_map<uint32, TalentEntry const*> TalentBySpellIDMap;
+
extern DBCStorage <AchievementEntry> sAchievementStore;
extern DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore;
extern DBCStorage <AreaTableEntry> sAreaStore;// recommend access using functions
@@ -108,6 +109,7 @@ extern DBCStorage <CharTitlesEntry> sCharTitlesStore;
extern DBCStorage <ChrClassesEntry> sChrClassesStore;
extern DBCStorage <ChrRacesEntry> sChrRacesStore;
extern DBCStorage <ChrPowerTypesEntry> sChrPowerTypesStore;
+extern DBCStorage <ChrSpecializationEntry> sChrSpecializationStore;
extern DBCStorage <CinematicSequencesEntry> sCinematicSequencesStore;
extern DBCStorage <CreatureDisplayInfoEntry> sCreatureDisplayInfoStore;
extern DBCStorage <CreatureDisplayInfoExtraEntry> sCreatureDisplayInfoExtraStore;
@@ -197,6 +199,8 @@ extern DBCStorage <SkillLineEntry> sSkillLineStore;
extern DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore;
extern DBCStorage <SkillTiersEntry> sSkillTiersStore;
extern DBCStorage <SoundEntriesEntry> sSoundEntriesStore;
+extern DBCStorage <SpecializationSpellsEntry> sSpecializationSpellsStore;
+extern SpecializationSpellsBySpecStore sSpecializationSpellsBySpecStore;
extern DBCStorage <SpellCastTimesEntry> sSpellCastTimesStore;
extern DBCStorage <SpellCategoryEntry> sSpellCategoryStore;
extern DBCStorage <SpellDurationEntry> sSpellDurationStore;
@@ -224,7 +228,7 @@ extern DBCStorage <SpellTotemsEntry> sSpellTotemsStore;
//extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <TalentEntry> sTalentStore;
-extern DBCStorage <TalentTabEntry> sTalentTabStore;
+extern TalentBySpellIDMap sTalentBySpellIDMap;
extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;
extern DBCStorage <TaxiPathEntry> sTaxiPathStore;
extern TaxiMask sTaxiNodesMask;
diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h
index 366db74dd8b..f3b6355091e 100644
--- a/src/server/game/DataStores/DBCStructure.h
+++ b/src/server/game/DataStores/DBCStructure.h
@@ -776,6 +776,26 @@ struct ChrPowerTypesEntry
uint32 PowerType; // 2
};
+#define MAX_MASTERY_SPELLS 2
+
+struct ChrSpecializationEntry
+{
+ uint32 ID; // 0 Specialization ID
+ //char* BackgroundFile; // 1
+ uint32 ClassID; // 2
+ uint32 MasterySpellID[MAX_MASTERY_SPELLS]; // 3
+ uint32 OrderIndex; // 4
+ uint32 PetTalentType; // 5
+ uint32 Role; // 6 (0 - Tank, 1 - Healer, 2 - DPS)
+ uint32 SpellIconID; // 7
+ uint32 RaidBuffs; // 8
+ uint32 Flags; // 9
+ //char* Name_lang; // 10
+ //char* Name2_lang; // 11 Same as name_lang?
+ //char* Description_lang; // 12
+ uint32 PrimaryStatOrder[2]; // 13-14
+};
+
struct CinematicSequencesEntry
{
uint32 ID; // 0
@@ -1787,6 +1807,16 @@ struct SoundEntriesEntry
//uint32 BusOverwriteID; // 55
};
+// SpecializationSpells.dbc
+struct SpecializationSpellsEntry
+{
+ uint32 ID; // 0
+ uint32 SpecID; // 1
+ uint32 SpellID; // 2
+ uint32 OverridesSpellID; // 3
+ //char* Description_lang; // 4
+};
+
// SpellEffect.dbc
struct SpellEffectEntry
{
@@ -2091,14 +2121,6 @@ struct SpellItemEnchantmentConditionEntry
uint32 RTOperand[5]; // 10-14
uint8 Logic[5]; // 15-16
//uint8 Padding[3]; // 16
-
- /*uint32 ID; // 0 m_ID
- uint8 Color[5]; // 1-5 m_lt_operandType[5]
- //uint32 LT_Operand[5]; // 6-10 m_lt_operand[5]
- uint8 Comparator[5]; // 11-15 m_operator[5]
- uint8 CompareColor[5]; // 15-20 m_rt_operandType[5]
- uint32 Value[5]; // 21-25 m_rt_operand[5]
- //uint8 Logic[5] // 25-30 m_logic[5]*/
};
struct StableSlotPricesEntry
@@ -2109,56 +2131,28 @@ struct StableSlotPricesEntry
struct SummonPropertiesEntry
{
- uint32 Id; // 0
- uint32 Category; // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
- uint32 Faction; // 2, 14 rows > 0
- uint32 Type; // 3, see enum
- int32 Slot; // 4, 0-6
- uint32 Flags; // 5
+ uint32 ID; // 0
+ uint32 Category; // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
+ uint32 Faction; // 2, 14 rows > 0
+ uint32 Type; // 3, see enum
+ int32 Slot; // 4, 0-6
+ uint32 Flags; // 5
};
-#define MAX_TALENT_RANK 5
#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK
-#define MAX_TALENT_TABS 3
struct TalentEntry
{
- uint32 TalentID; // 0
- uint32 TalentTab; // 1 index in TalentTab.dbc (TalentTabEntry)
- uint32 Row; // 2
- uint32 Col; // 3
- uint32 RankID[MAX_TALENT_RANK]; // 4-8
- uint32 DependsOn; // 9 m_prereqTalent (Talent.dbc)
- // 10-11 part of prev field
- uint32 DependsOnRank; // 12 m_prereqRank
- // 13-14 part of prev field
- //uint32 needAddInSpellBook; // 15 m_flags also need disable higest ranks on reset talent tree
- //uint32 unk2; // 16 m_requiredSpellID
- //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
-{
- uint32 TalentTabID; // 0
- //char* name; // 1 m_name_lang
- //unit32 spellicon; // 2 m_spellIconID
- uint32 ClassMask; // 3 m_classMask
- uint32 petTalentMask; // 4 m_petTalentMask
- uint32 tabpage; // 5 m_orderIndex
- //char* internalname; // 6 m_backgroundFile
- //char* description; // 7
- //uint32 rolesMask; // 8 4.0.0
- uint32 MasterySpellId[MAX_MASTERY_SPELLS]; // 9-10 passive mastery bonus spells?
-};
-
-struct TalentTreePrimarySpellsEntry
-{
- //uint32 Id; // 0 index
- uint32 TalentTree; // 1 entry from TalentTab.dbc
- uint32 SpellId; // 2 spell id to learn
- //uint32 Flags; // 3 some kind of flags
+ uint32 ID; // 0
+ uint32 SpecID; // 1 0 - any specialization
+ uint32 TierID; // 2 0-6
+ uint32 ColumnIndex; // 3 0-2
+ uint32 SpellID; // 4
+ uint32 Flags; // 5 All 0
+ uint32 CategoryMask[2]; // 6 All 0
+ uint32 ClassID; // 7
+ uint32 OverridesSpellID; // 8 spellid that is replaced by talent
+ //char* Description_lang
};
struct TaxiNodesEntry
@@ -2471,16 +2465,7 @@ struct MapDifficulty
bool hasErrorMessage;
};
-struct TalentSpellPos
-{
- TalentSpellPos() : talent_id(0), rank(0) { }
- TalentSpellPos(uint16 _talent_id, uint8 _rank) : talent_id(_talent_id), rank(_rank) { }
-
- uint16 talent_id;
- uint8 rank;
-};
-
-typedef std::map<uint32, TalentSpellPos> TalentSpellPosMap;
+typedef std::map<uint32, uint32> TalentSpellPosMap;
struct TaxiPathBySourceAndDestination
{
diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h
index c6b2fc34afe..362d4579bee 100644
--- a/src/server/game/DataStores/DBCfmt.h
+++ b/src/server/game/DataStores/DBCfmt.h
@@ -41,6 +41,7 @@ char const ChatChannelsEntryfmt[] = "nixsx";
char const ChrClassesEntryfmt[] = "nixsxxxixiiiixxxxx";
char const ChrRacesEntryfmt[] = "niixiixxxxxxiisxxxxxxxxxxxxxxxxxxxxxxxxx";
char const ChrClassesXPowerTypesfmt[] = "nii";
+char const ChrSpecializationEntryfmt[] = "nxiiiiiiiiixxxii";
char const CinematicSequencesEntryfmt[] = "nxxxxxxxxx";
char const CreatureDisplayInfofmt[] = "nixifxxxxxxxxxxxxxxxx";
char const CreatureDisplayInfoExtrafmt[] = "dixxxxxxxxxxxxxxxxxxx";
@@ -125,6 +126,7 @@ char const SkillLineAbilityfmt[] = "niiiiiiiiiiii";
char const SkillRaceClassInfofmt[] = "diiiixxi";
char const SkillTiersfmt[] = "niiiiiiiiiiiiiiii";
char const SoundEntriesfmt[] = "nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+char const SpecializationSpellsEntryfmt[] = "niiix";
char const SpellCastTimefmt[] = "nixx";
char const SpellCategoriesEntryfmt[] = "diiiiiiiix";
char const SpellCategoryfmt[] = "nixxxx";
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 9d8d0d1f6e9..0fe830f861e 100644
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -1405,25 +1405,7 @@ bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpel
newspell.active = active;
// talent: unlearn all other talent ranks (high and low)
- if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
- {
- if (TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentPos->talent_id))
- {
- for (uint8 i = 0; i < MAX_TALENT_RANK; ++i)
- {
- // skip learning spell and no rank spell case
- uint32 rankSpellId = talentInfo->RankID[i];
- if (!rankSpellId || rankSpellId == spellId)
- continue;
-
- // skip unknown ranks
- if (!HasSpell(rankSpellId))
- continue;
- removeSpell(rankSpellId, false, false);
- }
- }
- }
- else if (spellInfo->IsRanked())
+ if (spellInfo->IsRanked())
{
for (PetSpellMap::const_iterator itr2 = m_spells.begin(); itr2 != m_spells.end(); ++itr2)
{
@@ -1465,15 +1447,6 @@ bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpel
if (newspell.active == ACT_ENABLED)
ToggleAutocast(spellInfo, true);
- uint32 talentCost = GetTalentSpellCost(spellId);
- if (talentCost)
- {
- int32 free_points = GetMaxTalentPointsForLevel(getLevel());
- m_usedTalentCount += talentCost;
- // update free talent points
- free_points-=m_usedTalentCount;
- SetFreeTalentPoints(free_points > 0 ? free_points : 0);
- }
return true;
}
@@ -1563,18 +1536,6 @@ bool Pet::removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab)
RemoveAurasDueToSpell(spell_id);
- uint32 talentCost = GetTalentSpellCost(spell_id);
- if (talentCost > 0)
- {
- if (m_usedTalentCount > talentCost)
- m_usedTalentCount -= talentCost;
- else
- m_usedTalentCount = 0;
- // update free talent points
- int32 free_points = GetMaxTalentPointsForLevel(getLevel()) - m_usedTalentCount;
- SetFreeTalentPoints(free_points > 0 ? free_points : 0);
- }
-
if (learn_prev)
{
if (uint32 prev_id = sSpellMgr->GetPrevSpellInChain (spell_id))
@@ -1622,6 +1583,7 @@ void Pet::InitPetCreateSpells()
bool Pet::resetTalents()
{
+ /* TODO: 6.x remove pet talents
Player* player = GetOwner();
// not need after this call
@@ -1689,12 +1651,13 @@ bool Pet::resetTalents()
SetFreeTalentPoints(talentPointsForLevel);
if (!m_loading)
- player->PetSpellInitialize();
+ player->PetSpellInitialize();*/
return true;
}
void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/)
{
+ /* TODO: 6.x remove pet talents
// not need after this call
if (owner->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS))
owner->RemoveAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS, true);
@@ -1767,7 +1730,7 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/)
ss << ')';
- CharacterDatabase.Execute(ss.str().c_str());
+ CharacterDatabase.Execute(ss.str().c_str());*/
}
void Pet::InitTalentForLevel()
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 6b1e8fc95fa..016666e2945 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2984,40 +2984,6 @@ void Player::GiveLevel(uint8 level)
void Player::InitTalentForLevel()
{
- uint8 level = getLevel();
- // talents base at level diff (talents = level - 9 but some can be used already)
- if (level < 10)
- {
- // Remove all talent points
- if (GetUsedTalentCount() > 0) // Free any used talents
- {
- ResetTalents(true);
- SetFreeTalentPoints(0);
- }
- }
- else
- {
- if (level < sWorld->getIntConfig(CONFIG_MIN_DUALSPEC_LEVEL) || GetSpecsCount() == 0)
- {
- SetSpecsCount(1);
- SetActiveSpec(0);
- }
-
- uint32 talentPointsForLevel = CalculateTalentsPoints();
-
- // if used more that have then reset
- if (GetUsedTalentCount() > talentPointsForLevel)
- {
- if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_MORE_TALENTS_THAN_ALLOWED))
- ResetTalents(true);
- else
- SetFreeTalentPoints(0);
- }
- // else update amount of free points
- else
- SetFreeTalentPoints(talentPointsForLevel - GetUsedTalentCount());
- }
-
if (!GetSession()->PlayerLoading())
SendTalentsInfoData(false); // update at client
}
@@ -3344,6 +3310,7 @@ void DeleteSpellFromAllPlayers(uint32 spellId)
bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
{
+ /* TODO: 6.x update talent system
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
@@ -3404,6 +3371,7 @@ bool Player::AddTalent(uint32 spellId, uint8 spec, bool learning)
(*GetTalentMap(spec))[spellId] = newtalent;
return true;
}
+ */
return false;
}
@@ -3552,24 +3520,8 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
if (!disabled_case) // skip new spell adding if spell already known (disabled spells case)
{
- // talent: unlearn all other talent ranks (high and low)
- if (TalentSpellPos const* talentPos = GetTalentSpellPos(spellId))
- {
- 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 == spellId)
- continue;
-
- RemoveSpell(rankSpellId, false, false);
- }
- }
- }
// non talent spell: learn low ranks (recursive call)
- else if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spellId))
+ if (uint32 prev_spell = sSpellMgr->GetPrevSpellInChain(spellId))
{
if (!IsInWorld() || disabled) // at spells loading, no output, but allow save
AddSpell(prev_spell, active, true, true, disabled, false, fromSkill);
@@ -3632,11 +3584,9 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
return false;
}
- uint32 talentCost = GetTalentSpellCost(spellId);
-
// cast talents with SPELL_EFFECT_LEARN_SPELL (other dependent spells will learned later as not auto-learned)
// note: all spells with SPELL_EFFECT_LEARN_SPELL isn't passive
- if (!loading && talentCost > 0 && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
+ if (!loading && spellInfo->HasEffect(SPELL_EFFECT_LEARN_SPELL))
{
// ignore stance requirement for talent learn spell (stance set for spell only for client spell description show)
CastSpell(this, spellId, true);
@@ -3653,9 +3603,6 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent
return false;
}
- // update used talent points count
- SetUsedTalentCount(GetUsedTalentCount() + talentCost);
-
// update free primary prof.points (if any, can be none in case GM .learn prof. learning)
if (uint32 freeProfs = GetFreePrimaryProfessionPoints())
{
@@ -3773,8 +3720,8 @@ bool Player::IsNeedCastPassiveSpellAtLearn(SpellInfo const* spellInfo) const
bool Player::IsCurrentSpecMasterySpell(SpellInfo const* spellInfo) const
{
- if (TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
- return spellInfo->Id == talentTab->MasterySpellId[0] || spellInfo->Id == talentTab->MasterySpellId[1];
+ if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(GetActiveSpec())))
+ return spellInfo->Id == chrSpec->MasterySpellID[0] || spellInfo->Id == chrSpec->MasterySpellID[1];
return false;
}
@@ -3829,7 +3776,7 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
// unlearn non talent higher ranks (recursive)
if (uint32 nextSpell = sSpellMgr->GetNextSpellInChain(spell_id))
{
- if (HasSpell(nextSpell) && !GetTalentSpellPos(nextSpell))
+ if (HasSpell(nextSpell) && !GetTalentBySpellID(nextSpell))
RemoveSpell(nextSpell, disabled, false);
}
//unlearn spells dependent from recently removed spells
@@ -3842,8 +3789,6 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
if (itr == m_spells.end())
return; // already unleared
- bool giveTalentPoints = disabled || !itr->second->disabled;
-
bool cur_active = itr->second->active;
bool cur_dependent = itr->second->dependent;
@@ -3871,16 +3816,6 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
if (PetAura const* petSpell = sSpellMgr->GetPetAura(spell_id, i))
RemovePetAura(petSpell);
- // free talent points
- uint32 talentCosts = GetTalentSpellCost(spell_id);
- if (talentCosts > 0 && giveTalentPoints)
- {
- if (talentCosts < GetUsedTalentCount())
- SetUsedTalentCount(GetUsedTalentCount() - talentCosts);
- else
- SetUsedTalentCount(0);
- }
-
// update free primary prof.points (if not overflow setting, can be in case GM use before .learn prof. learning)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
if (spellInfo && spellInfo->IsPrimaryProfessionFirstRank())
@@ -3938,16 +3873,9 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank)
if (uint32 prev_id = sSpellMgr->GetPrevSpellInChain(spell_id))
{
- // if talent then lesser rank also talent and need learn
- if (talentCosts)
- {
- // I cannot see why mangos has these lines.
- //if (learn_low_rank)
- // learnSpell(prev_id, false);
- }
// if ranked non-stackable spell: need activate lesser rank and update dendence state
/// No need to check for spellInfo != NULL here because if cur_active is true, then that means that the spell was already in m_spells, and only valid spells can be pushed there.
- else if (cur_active && !spellInfo->IsStackableWithRanks() && spellInfo->IsRanked())
+ if (cur_active && !spellInfo->IsStackableWithRanks() && spellInfo->IsRanked())
{
// need manually update dependence state (learn spell ignore like attempts)
PlayerSpellMap::iterator prev_itr = m_spells.find(prev_id);
@@ -4191,14 +4119,6 @@ bool Player::ResetTalents(bool no_cost)
if (HasAtLoginFlag(AT_LOGIN_RESET_TALENTS))
RemoveAtLoginFlag(AT_LOGIN_RESET_TALENTS, true);
- uint32 talentPointsForLevel = CalculateTalentsPoints();
-
- if (!GetUsedTalentCount())
- {
- SetFreeTalentPoints(talentPointsForLevel);
- return false;
- }
-
uint32 cost = 0;
if (!no_cost && !sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST))
@@ -4221,54 +4141,52 @@ bool Player::ResetTalents(bool no_cost)
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)
+ if (getClass() != talentInfo->ClassID)
continue;
- for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
- {
- // skip non-existant talent ranks
- if (talentInfo->RankID[rank] == 0)
- continue;
- const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]);
- if (!_spellEntry)
- continue;
- RemoveSpell(talentInfo->RankID[rank], true);
- // search for spells that the talent teaches and unlearn them
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
- RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true);
- // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
- PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->RankID[rank]);
- if (plrTalent != GetTalentMap(GetActiveSpec())->end())
- plrTalent->second->state = PLAYERSPELL_REMOVED;
- }
- }
+ const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
- // Remove spec specific spells
- uint32 const* talentTabs = GetTalentTabPages(getClass());
- for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
- {
- if (std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentTabs[i]))
- for (size_t j = 0; j < specSpells->size(); ++j)
- RemoveSpell(specSpells->at(j), true);
+ if (!_spellEntry)
+ continue;
+
+ RemoveSpell(talentInfo->SpellID, true);
+
+ // search for spells that the talent teaches and unlearn them
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
+ RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true);
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabs[i]);
- for (uint32 j = 0; j < MAX_MASTERY_SPELLS; ++j)
- if (uint32 mastery = talentTabInfo->MasterySpellId[j])
- RemoveAurasDueToSpell(mastery);
+ // if this talent rank can be found in the PlayerTalentMap, mark the talent as removed so it gets deleted
+ PlayerTalentMap::iterator plrTalent = GetTalentMap(GetActiveSpec())->find(talentInfo->SpellID);
+ if (plrTalent != GetTalentMap(GetActiveSpec())->end())
+ plrTalent->second->state = PLAYERSPELL_REMOVED;
}
+ // Remove all specialization specific spells and give default ones which were overriden
+ auto specSpells = sSpecializationSpellsBySpecStore.find(GetTalentSpec(GetActiveSpec()));
+ if (specSpells != sSpecializationSpellsBySpecStore.end())
+ {
+ for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
+ {
+ SpecializationSpellsEntry const* specSpell = *it;
+ if (HasSpell(specSpell->SpellID)) {
+ RemoveSpell(specSpell->SpellID, true);
+ if (specSpell->OverridesSpellID)
+ LearnSpell(specSpell->OverridesSpellID, false);
+ }
+ }
+ }
- SetPrimaryTalentTree(GetActiveSpec(), 0);
- SetFreeTalentPoints(talentPointsForLevel);
+ // Unlearn masteries
+ ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(GetActiveSpec()));
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (uint32 mastery = chrSpec->MasterySpellID[i])
+ RemoveAurasDueToSpell(mastery);
+
+ SetTalentSpec(GetActiveSpec(), 0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveTalents(trans);
@@ -15229,12 +15147,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
SetTitle(titleEntry);
}
- if (uint32 talents = quest->GetBonusTalents())
- {
- AddQuestRewardedTalentCount(talents);
- InitTalentForLevel();
- }
-
// Send reward mail
if (uint32 mail_template_id = quest->GetRewMailTemplateId())
{
@@ -17534,15 +17446,17 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
}
// Only load selected specializations, learning mastery spells requires this
- Tokenizer talentTrees(fields[26].GetString(), ' ', MAX_TALENT_SPECS);
+ Tokenizer talentSpecs(fields[26].GetString(), ' ', MAX_TALENT_SPECS);
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
- if (i >= talentTrees.size())
+ if (i >= talentSpecs.size())
break;
- uint32 talentTree = atol(talentTrees[i]);
- if (sTalentTabStore.LookupEntry(talentTree))
- SetPrimaryTalentTree(i, talentTree);
+ uint32 talentSpec = atol(talentSpecs[i]);
+ if (sChrSpecializationStore.LookupEntry(talentSpec))
+ SetTalentSpec(i, talentSpec);
+ else
+ SetAtLoginFlag(AT_LOGIN_RESET_TALENTS);
}
_LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS));
@@ -17632,17 +17546,6 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder)
SetPower(POWER_ECLIPSE, 0);
- // Verify loaded talent specializations
- for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
- {
- if (i >= talentTrees.size())
- break;
-
- uint32 talentTree = atol(talentTrees[i]);
- if (talentTree != 0 && !sTalentTabStore.LookupEntry(talentTree) && i == GetActiveSpec())
- SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents
- }
-
TC_LOG_DEBUG("entities.player.loading", "The value of player %s after load item and aura is: ", m_name.c_str());
outDebugValues();
@@ -18494,9 +18397,6 @@ void Player::_LoadQuestStatusRewarded(PreparedQueryResult result)
if (CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(quest->GetCharTitleId()))
SetTitle(titleEntry);
}
-
- if (uint32 talents = quest->GetBonusTalents())
- AddQuestRewardedTalentCount(talents);
}
m_RewardedQuests.insert(quest_id);
@@ -19209,7 +19109,7 @@ void Player::SaveToDB(bool create /*=false*/)
ss.str("");
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
- ss << GetPrimaryTalentTree(i) << " ";
+ ss << GetTalentSpec(i) << " ";
stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
@@ -19338,7 +19238,7 @@ void Player::SaveToDB(bool create /*=false*/)
ss.str("");
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
- ss << GetPrimaryTalentTree(i) << " ";
+ ss << GetTalentSpec(i) << " ";
stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
@@ -23404,11 +23304,6 @@ void Player::ResetSpells(bool myClassOnly)
if (spellInfo->SpellFamilyName != family)
continue;
- // skip spells with first rank learned as talent (and all talents then also)
- uint32 firstRank = spellInfo->GetFirstRankSpell()->Id;
- if (GetTalentSpellCost(firstRank) > 0)
- continue;
-
// skip broken spells
if (!SpellMgr::IsSpellValid(spellInfo, this, false))
continue;
@@ -25314,38 +25209,6 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot)
SendEquipError(msg, NULL, NULL, item->itemid);
}
-// 6.x - removeme
-uint32 Player::CalculateTalentsPoints() const
-{
- // this dbc file has entries only up to level 100
- /*NumTalentsAtLevelEntry const* count = sNumTalentsAtLevelStore.LookupEntry(std::min<uint32>(getLevel(), 100));
- if (!count)
- return 0;
-
- float baseForLevel = count->Talents;
-
- if (getClass() != CLASS_DEATH_KNIGHT || GetMapId() != 609)
- return uint32(baseForLevel * sWorld->getRate(RATE_TALENT));
-
- // Death Knight starting level
- // hardcoded here - number of quest awarded talents is equal to number of talents any other class would have at level 55
- if (getLevel() < 55)
- return 0;
-
- NumTalentsAtLevelEntry const* dkBase = sNumTalentsAtLevelStore.LookupEntry(55);
- if (!dkBase)
- return 0;
-
- float talentPointsForLevel = count->Talents - dkBase->Talents;
- talentPointsForLevel += float(GetQuestRewardedTalentCount());
-
- if (talentPointsForLevel > baseForLevel)
- talentPointsForLevel = baseForLevel;
-
- return uint32(talentPointsForLevel * sWorld->getRate(RATE_TALENT));*/
- return 0;
-}
-
bool Player::IsKnowHowFlyIn(uint32 mapid, uint32 zone) const
{
// continent checked in SpellInfo::CheckLocation at cast and area update
@@ -25651,108 +25514,26 @@ void Player::CompletedAchievement(AchievementEntry const* entry)
m_achievementMgr->CompletedAchievement(entry, this);
}
-bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
+bool Player::LearnTalent(uint32 talentId)
{
- uint32 CurTalentPoints = GetFreeTalentPoints();
-
- if (CurTalentPoints == 0)
- return false;
-
- if (talentRank >= MAX_TALENT_RANK)
- return false;
-
TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
if (!talentInfo)
return false;
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
-
- if (!talentTabInfo)
- return false;
-
// prevent learn talent for different class (cheating)
- if ((getClassMask() & talentTabInfo->ClassMask) == 0)
+ if (getClass() != talentInfo->ClassID)
return false;
- // find current max talent rank (0~5)
- uint8 curtalent_maxrank = 0; // 0 = not learned any rank
- for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
- {
- if (talentInfo->RankID[rank] && HasSpell(talentInfo->RankID[rank]))
- {
- curtalent_maxrank = (rank + 1);
- break;
- }
- }
-
- // we already have same or higher talent rank learned
- if (curtalent_maxrank >= (talentRank + 1))
- return false;
-
- // check if we have enough talent points
- if (CurTalentPoints < (talentRank - curtalent_maxrank + 1))
- return false;
-
- // Check if it requires another talent
- if (talentInfo->DependsOn > 0)
- {
- if (TalentEntry const* depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
- {
- bool hasEnoughRank = false;
- for (uint8 rank = talentInfo->DependsOnRank; rank < MAX_TALENT_RANK; rank++)
- {
- if (depTalentInfo->RankID[rank] != 0)
- if (HasSpell(depTalentInfo->RankID[rank]))
- hasEnoughRank = true;
- }
- if (!hasEnoughRank)
- return false;
- }
- }
-
- // Find out how many points we have in this field
- uint32 spentPoints = 0;
- uint32 primaryTreeTalents = 0;
- uint32 tTab = talentInfo->TalentTab;
- bool isMainTree = GetPrimaryTalentTree(GetActiveSpec()) == tTab || !GetPrimaryTalentTree(GetActiveSpec());
-
- if (talentInfo->Row > 0 || !isMainTree)
- {
- for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents.
- {
- if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // Someday, someone needs to revamp the way talents are tracked
- {
- for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++)
- {
- if (tmpTalent->RankID[rank] != 0)
- {
- if (HasSpell(tmpTalent->RankID[rank]))
- {
- if (tmpTalent->TalentTab == tTab)
- spentPoints += (rank + 1);
- if (tmpTalent->TalentTab == GetPrimaryTalentTree(GetActiveSpec()))
- primaryTreeTalents += (rank + 1);
- }
- }
- }
- }
- }
- }
-
- // not have required min points spent in talent tree
- if (spentPoints < (talentInfo->Row * MAX_TALENT_RANK))
- return false;
-
- // player has not spent 31 talents in main tree before attempting to learn other tree's talents
- if (!isMainTree && primaryTreeTalents < REQ_PRIMARY_TREE_TALENTS)
+ // Check player level.
+ if (getLevel() < (15*talentInfo->TierID + 15))
return false;
// spell not set in talent.dbc
- uint32 spellid = talentInfo->RankID[talentRank];
+ uint32 spellid = talentInfo->SpellID;
if (spellid == 0)
{
- TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
+ TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u spell id = 0", talentId);
return false;
}
@@ -25764,162 +25545,37 @@ bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
LearnSpell(spellid, false);
AddTalent(spellid, GetActiveSpec(), true);
- TC_LOG_INFO("misc", "TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, GetActiveSpec());
+ TC_LOG_INFO("misc", "TalentID: %u Spell: %u Spec: %u\n", talentId, spellid, GetActiveSpec());
// set talent tree for player
- if (!GetPrimaryTalentTree(GetActiveSpec()))
- {
- SetPrimaryTalentTree(GetActiveSpec(), talentInfo->TalentTab);
- std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab);
- if (specSpells)
- for (size_t i = 0; i < specSpells->size(); ++i)
- LearnSpell(specSpells->at(i), false);
-
- if (CanUseMastery())
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(talentTabInfo->MasterySpellId[i]))
- if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell))
- CastSpell(this, masterySpell->Id, true);
- }
-
- // update free talent points
- SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
- return true;
-}
-
-void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank)
-{
- Pet* pet = GetPet();
-
- if (!pet)
- return;
-
- if (petGuid != pet->GetGUID())
- return;
-
- uint32 CurTalentPoints = pet->GetFreeTalentPoints();
-
- if (CurTalentPoints == 0)
- return;
-
- if (talentRank >= MAX_PET_TALENT_RANK)
- return;
-
- TalentEntry const* talentInfo = sTalentStore.LookupEntry(talentId);
-
- if (!talentInfo)
- return;
-
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
-
- if (!talentTabInfo)
- return;
-
- CreatureTemplate const* ci = pet->GetCreatureTemplate();
-
- if (!ci)
- return;
-
- CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
-
- if (!pet_family)
- return;
-
- if (pet_family->PetTalentType < 0) // not hunter pet
- return;
-
- // prevent learn talent for different family (cheating)
- if (!((1 << pet_family->PetTalentType) & talentTabInfo->petTalentMask))
- return;
-
- // find current max talent rank (0~5)
- uint8 curtalent_maxrank = 0; // 0 = not learned any rank
- for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
- {
- if (talentInfo->RankID[rank] && pet->HasSpell(talentInfo->RankID[rank]))
- {
- curtalent_maxrank = (rank + 1);
- break;
- }
- }
-
- // we already have same or higher talent rank learned
- if (curtalent_maxrank >= (talentRank + 1))
- return;
-
- // check if we have enough talent points
- if (CurTalentPoints < (talentRank - curtalent_maxrank + 1))
- return;
-
- // Check if it requires another talent
- if (talentInfo->DependsOn > 0)
+ if (!GetTalentSpec(GetActiveSpec()))
{
- if (TalentEntry const* depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn))
- {
- bool hasEnoughRank = false;
- for (uint8 rank = talentInfo->DependsOnRank; rank < MAX_TALENT_RANK; rank++)
- {
- if (depTalentInfo->RankID[rank] != 0)
- if (pet->HasSpell(depTalentInfo->RankID[rank]))
- hasEnoughRank = true;
- }
- if (!hasEnoughRank)
- return;
- }
- }
-
- // Find out how many points we have in this field
- uint32 spentPoints = 0;
+ SetTalentSpec(GetActiveSpec(), talentInfo->SpecID);
- uint32 tTab = talentInfo->TalentTab;
- if (talentInfo->Row > 0)
- {
- uint32 numRows = sTalentStore.GetNumRows();
- for (uint32 i = 0; i < numRows; ++i) // Loop through all talents.
+ // Replace default spells by specialization spells
+ auto specSpells = sSpecializationSpellsBySpecStore.find(talentInfo->SpecID);
+ if (specSpells != sSpecializationSpellsBySpecStore.end())
{
- // Someday, someone needs to revamp
- const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i);
- if (tmpTalent) // the way talents are tracked
+ for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
{
- if (tmpTalent->TalentTab == tTab)
- {
- for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++)
- {
- if (tmpTalent->RankID[rank] != 0)
- {
- if (pet->HasSpell(tmpTalent->RankID[rank]))
- {
- spentPoints += (rank + 1);
- }
- }
- }
+ SpecializationSpellsEntry const* specSpell = *it;
+ if (HasSpell(specSpell->OverridesSpellID)) {
+ RemoveSpell(specSpell->OverridesSpellID, true);
+ LearnSpell(specSpell->SpellID, false);
}
}
}
- }
-
- // not have required min points spent in talent tree
- if (spentPoints < (talentInfo->Row * MAX_PET_TALENT_RANK))
- return;
- // spell not set in talent.dbc
- uint32 spellid = talentInfo->RankID[talentRank];
- if (spellid == 0)
- {
- TC_LOG_ERROR("entities.player", "Talent.dbc have for talent: %u Rank: %u spell id = 0", talentId, talentRank);
- return;
+ if (CanUseMastery()) {
+ ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(talentInfo->SpecID);
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (SpellInfo const* masterySpell = sSpellMgr->GetSpellInfo(chrSpec->MasterySpellID[i]))
+ if (masterySpell->IsPassive() && IsNeedCastPassiveSpellAtLearn(masterySpell))
+ CastSpell(this, masterySpell->Id, true);
+ }
}
- // already known
- if (pet->HasSpell(spellid))
- return;
-
- // learn! (other talent ranks will unlearned at learning)
- pet->learnSpell(spellid);
- TC_LOG_INFO("entities.player", "PetTalentID: %u Rank: %u Spell: %u\n", talentId, talentRank, spellid);
-
- // update free talent points
- pet->SetFreeTalentPoints(CurTalentPoints - (talentRank - curtalent_maxrank + 1));
+ return true;
}
void Player::AddKnownCurrency(uint32 itemId)
@@ -25998,6 +25654,7 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const
void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
{
+ /* TODO: 6.x update with new talent system (and move to packet class)
*data << uint32(GetFreeTalentPoints()); // unspentTalentPoints
*data << uint8(GetSpecsCount()); // talent group count (0, 1 or 2)
*data << uint8(GetActiveSpec()); // talent group index (0 or 1)
@@ -26062,10 +25719,12 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
*data << uint16(GetGlyph(specIdx, i)); // GlyphProperties.dbc
}
}
+ */
}
void Player::BuildPetTalentsInfoData(WorldPacket* data)
{
+ /* TODO: 6.x update with new talent system (and move to packet class)
uint32 unspentTalentPoints = 0;
size_t pointsPos = data->wpos();
*data << uint32(unspentTalentPoints); // [PH], unspentTalentPoints
@@ -26133,11 +25792,12 @@ void Player::BuildPetTalentsInfoData(WorldPacket* data)
data->put<uint8>(countPos, talentIdCount); // put real count
break;
- }
+ }*/
}
void Player::SendTalentsInfoData(bool pet)
{
+ /* TODO: 6.x update with new talent system (and move to packet class)
WorldPacket data(SMSG_TALENTS_INFO, 50);
data << uint8(pet ? 1 : 0);
if (pet)
@@ -26145,6 +25805,7 @@ void Player::SendTalentsInfoData(bool pet)
else
BuildPlayerTalentsInfoData(&data);
GetSession()->SendPacket(&data);
+ */
}
void Player::BuildEnchantmentsInfoData(WorldPacket* data)
@@ -26604,49 +26265,35 @@ void Player::ActivateSpec(uint8 spec)
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)
+ if (getClass() != talentInfo->ClassID)
continue;
- for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
- {
- // skip non-existant talent ranks
- if (talentInfo->RankID[rank] == 0)
- continue;
- RemoveSpell(talentInfo->RankID[rank], true); // removes the talent, and all dependant, learned, and chained spells..
- if (const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]))
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) // search through the SpellInfo for valid trigger spells
- if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL)
- RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true); // and remove any spells that the talent teaches
- // 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;
- }
+ RemoveSpell(talentInfo->SpellID, true);
}
- // Remove spec specific spells
- for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
+ // Unlearn specialization specific spells
+ auto specSpells = sSpecializationSpellsBySpecStore.find(GetTalentSpec(GetActiveSpec()));
+ if (specSpells != sSpecializationSpellsBySpecStore.end())
{
- uint32 const* talentTabs = GetTalentTabPages(getClass());
- std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentTabs[i]);
- if (specSpells)
- for (size_t i = 0; i < specSpells->size(); ++i)
- RemoveSpell(specSpells->at(i), true);
-
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabs[i]);
- for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (uint32 mastery = talentTabInfo->MasterySpellId[i])
- RemoveSpell(mastery, true);
+ for (auto it = specSpells->second.begin(); it != specSpells->second.end(); ++it)
+ {
+ SpecializationSpellsEntry const* specSpell = *it;
+ if (HasSpell(specSpell->SpellID)) {
+ RemoveSpell(specSpell->SpellID, true);
+ LearnSpell(specSpell->OverridesSpellID, false);
+ }
+ }
}
+ // Unlearn mastery spells
+ ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(GetActiveSpec()));
+ for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
+ if (chrSpec->MasterySpellID[i])
+ RemoveSpell(chrSpec->MasterySpellID[i], true);
+
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
// remove secondary glyph
@@ -26654,8 +26301,8 @@ void Player::ActivateSpec(uint8 spec)
if (GlyphPropertiesEntry const* old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph))
RemoveAurasDueToSpell(old_gp->SpellID);
+ // Activate new spec
SetActiveSpec(spec);
- uint32 spentTalents = 0;
for (uint32 talentId = 0; talentId < sTalentStore.GetNumRows(); ++talentId)
{
@@ -26664,40 +26311,37 @@ void Player::ActivateSpec(uint8 spec)
if (!talentInfo)
continue;
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
-
- if (!talentTabInfo)
- continue;
-
// learn only talents for character class
- if ((getClassMask() & talentTabInfo->ClassMask) == 0)
+ if (getClass() != talentInfo->ClassID)
continue;
- // learn highest talent rank that exists in newly activated spec
- for (int8 rank = MAX_TALENT_RANK-1; rank >= 0; --rank)
+ if (HasTalent(talentInfo->SpellID, GetActiveSpec()))
{
- // skip non-existant talent ranks
- if (talentInfo->RankID[rank] == 0)
- continue;
- // if the talent can be found in the newly activated PlayerTalentMap
- if (HasTalent(talentInfo->RankID[rank], GetActiveSpec()))
- {
- LearnSpell(talentInfo->RankID[rank], false); // add the talent to the PlayerSpellMap
- spentTalents += (rank + 1); // increment the spentTalents count
- }
+ LearnSpell(talentInfo->SpellID, false);
}
}
- std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetPrimaryTalentTree(GetActiveSpec()));
- if (specSpells)
- for (size_t i = 0; i < specSpells->size(); ++i)
- LearnSpell(specSpells->at(i), false);
+ // Replace default spells with specialization specific spells
+ auto newSpecSpells = sSpecializationSpellsBySpecStore.find(GetTalentSpec(spec));
+ if (newSpecSpells != sSpecializationSpellsBySpecStore.end())
+ {
+ for (auto it = newSpecSpells->second.begin(); it != newSpecSpells->second.end(); ++it)
+ {
+ SpecializationSpellsEntry const* specSpell = *it;
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(specSpell->SpellID);
+ if (getLevel() >= spellInfo->BaseLevel) {
+ if (specSpell->OverridesSpellID)
+ RemoveSpell(specSpell->OverridesSpellID, true);
+ LearnSpell(specSpell->SpellID, false);
+ }
+ }
+ }
if (CanUseMastery())
- if (TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ if (ChrSpecializationEntry const* newChrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(spec)))
for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
- if (uint32 mastery = talentTabInfo->MasterySpellId[i])
- LearnSpell(mastery, false);
+ if (newChrSpec->MasterySpellID[i])
+ LearnSpell(newChrSpec->MasterySpellID[i], false);
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
@@ -26712,7 +26356,6 @@ void Player::ActivateSpec(uint8 spec)
SetGlyph(slot, glyph);
}
- SetUsedTalentCount(spentTalents);
InitTalentForLevel();
{
@@ -26731,7 +26374,7 @@ void Player::ActivateSpec(uint8 spec)
SetPower(pw, 0);
- if (!sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ if (!sChrSpecializationStore.LookupEntry(GetTalentSpec(spec)))
ResetTalents(true);
}
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index f01846f5593..d1a477ac5e1 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -123,38 +123,42 @@ struct PlayerTalent
extern uint32 const MasterySpells[MAX_CLASSES];
-enum TalentTree // talent tabs
-{
- TALENT_TREE_WARRIOR_ARMS = 746,
- TALENT_TREE_WARRIOR_FURY = 815,
- TALENT_TREE_WARRIOR_PROTECTION = 845,
- TALENT_TREE_PALADIN_HOLY = 831,
- TALENT_TREE_PALADIN_PROTECTION = 839,
- TALENT_TREE_PALADIN_RETRIBUTION = 855,
- TALENT_TREE_HUNTER_BEAST_MASTERY = 811,
- TALENT_TREE_HUNTER_MARKSMANSHIP = 807,
- TALENT_TREE_HUNTER_SURVIVAL = 809,
- TALENT_TREE_ROGUE_ASSASSINATION = 182,
- TALENT_TREE_ROGUE_COMBAT = 181,
- TALENT_TREE_ROGUE_SUBTLETY = 183,
- TALENT_TREE_PRIEST_DISCIPLINE = 760,
- TALENT_TREE_PRIEST_HOLY = 813,
- TALENT_TREE_PRIEST_SHADOW = 795,
- TALENT_TREE_DEATH_KNIGHT_BLOOD = 398,
- TALENT_TREE_DEATH_KNIGHT_FROST = 399,
- TALENT_TREE_DEATH_KNIGHT_UNHOLY = 400,
- TALENT_TREE_SHAMAN_ELEMENTAL = 261,
- TALENT_TREE_SHAMAN_ENHANCEMENT = 263,
- TALENT_TREE_SHAMAN_RESTORATION = 262,
- TALENT_TREE_MAGE_ARCANE = 799,
- TALENT_TREE_MAGE_FIRE = 851,
- TALENT_TREE_MAGE_FROST = 823,
- TALENT_TREE_WARLOCK_AFFLICTION = 871,
- TALENT_TREE_WARLOCK_DEMONOLOGY = 867,
- TALENT_TREE_WARLOCK_DESTRUCTION = 865,
- TALENT_TREE_DRUID_BALANCE = 752,
- TALENT_TREE_DRUID_FERAL_COMBAT = 750,
- TALENT_TREE_DRUID_RESTORATION = 748
+enum TalentSpecialization // talent tabs
+{
+ TALENT_SPEC_MAGE_ARCANE = 62,
+ TALENT_SPEC_MAGE_FIRE = 63,
+ TALENT_SPEC_MAGE_FROST = 64,
+ TALENT_SPEC_PALADIN_HOLY = 65,
+ TALENT_SPEC_PALADIN_PROTECTION = 66,
+ TALENT_SPEC_PALADIN_RETRIBUTION = 70,
+ TALENT_SPEC_WARRIOR_ARMS = 71,
+ TALENT_SPEC_WARRIOR_FURY = 72,
+ TALENT_SPEC_WARRIOR_PROTECTION = 73,
+ TALENT_SPEC_DRUID_BALANCE = 102,
+ TALENT_SPEC_DRUID_CAT = 103,
+ TALENT_SPEC_DRUID_BEAR = 104,
+ TALENT_SPEC_DRUID_RESTORATION = 105,
+ TALENT_SPEC_DEATHKNIGHT_BLOOD = 250,
+ TALENT_SPEC_DEATHKNIGHT_FROST = 251,
+ TALENT_SPEC_DEATHKNIGHT_UNHOLY = 252,
+ TALENT_SPEC_HUNTER_BEASTMASTER = 253,
+ TALENT_SPEC_HUNTER_MARKSMAN = 254,
+ TALENT_SPEC_HUNTER_SURVIVAL = 255,
+ TALENT_SPEC_PRIEST_DISCIPLINE = 256,
+ TALENT_SPEC_PRIEST_HOLY = 257,
+ TALENT_SPEC_PRIEST_SHADOW = 258,
+ TALENT_SPEC_ROGUE_ASSASSINATION = 259,
+ TALENT_SPEC_ROGUE_COMBAT = 260,
+ TALENT_SPEC_ROGUE_SUBTLETY = 261,
+ TALENT_SPEC_SHAMAN_ELEMENTAL = 262,
+ TALENT_SPEC_SHAMAN_ENCHANCEMENT = 263,
+ TALENT_SPEC_SHAMAN_RESTORATION = 264,
+ TALENT_SPEC_WARLOCK_AFFLICTION = 265,
+ TALENT_SPEC_WARLOCK_DEMONOLOGY = 266,
+ TALENT_SPEC_WARLOCK_DESTRUCTION = 267,
+ TALENT_SPEC_MONK_BREWMASTER = 268,
+ TALENT_SPEC_MONK_BATTLEDANCER = 269,
+ TALENT_SPEC_MONK_MISTWEAVER = 270
};
// Spell modifier (used for modify other spells)
@@ -1216,16 +1220,13 @@ private:
struct PlayerTalentInfo
{
- PlayerTalentInfo() :
- FreeTalentPoints(0), UsedTalentCount(0), QuestRewardedTalentCount(0),
- ResetTalentsCost(0), ResetTalentsTime(0),
- ActiveSpec(0), SpecsCount(1)
+ PlayerTalentInfo() : ResetTalentsCost(0), ResetTalentsTime(0), ActiveSpec(0), SpecsCount(1)
{
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
SpecInfo[i].Talents = new PlayerTalentMap();
memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
- SpecInfo[i].TalentTree = 0;
+ SpecInfo[i].TalentSpec = 0;
}
}
@@ -1243,12 +1244,9 @@ struct PlayerTalentInfo
{
PlayerTalentMap* Talents;
uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
- uint32 TalentTree;
+ uint32 TalentSpec;
} SpecInfo[MAX_TALENT_SPECS];
- uint32 FreeTalentPoints;
- uint32 UsedTalentCount;
- uint32 QuestRewardedTalentCount;
uint32 ResetTalentsCost;
time_t ResetTalentsTime;
uint8 ActiveSpec;
@@ -1818,22 +1816,16 @@ class Player : public Unit, public GridObject<Player>
std::string GetGuildName();
// Talents
- uint32 GetFreeTalentPoints() const { return _talentMgr->FreeTalentPoints; }
- void SetFreeTalentPoints(uint32 points) { _talentMgr->FreeTalentPoints = points; }
- uint32 GetUsedTalentCount() const { return _talentMgr->UsedTalentCount; }
- void SetUsedTalentCount(uint32 talents) { _talentMgr->UsedTalentCount = talents; }
- uint32 GetQuestRewardedTalentCount() const { return _talentMgr->QuestRewardedTalentCount; }
- void AddQuestRewardedTalentCount(uint32 points) { _talentMgr->QuestRewardedTalentCount += points; }
uint32 GetTalentResetCost() const { return _talentMgr->ResetTalentsCost; }
void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; }
uint32 GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; }
void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; }
- uint32 GetPrimaryTalentTree(uint8 spec) const { return _talentMgr->SpecInfo[spec].TalentTree; }
- void SetPrimaryTalentTree(uint8 spec, uint32 tree) { _talentMgr->SpecInfo[spec].TalentTree = tree; }
uint8 GetActiveSpec() const { return _talentMgr->ActiveSpec; }
void SetActiveSpec(uint8 spec){ _talentMgr->ActiveSpec = spec; }
uint8 GetSpecsCount() const { return _talentMgr->SpecsCount; }
void SetSpecsCount(uint8 count) { _talentMgr->SpecsCount = count; }
+ uint32 GetTalentSpec(uint8 spec) const { return _talentMgr->SpecInfo[spec].TalentSpec; }
+ void SetTalentSpec(uint8 spec, uint32 talentSpec) const { _talentMgr->SpecInfo[spec].TalentSpec = talentSpec; }
bool ResetTalents(bool no_cost = false);
uint32 GetNextResetTalentsCost() const;
@@ -1841,11 +1833,9 @@ class Player : public Unit, public GridObject<Player>
void BuildPlayerTalentsInfoData(WorldPacket* data);
void BuildPetTalentsInfoData(WorldPacket* data);
void SendTalentsInfoData(bool pet);
- bool LearnTalent(uint32 talentId, uint32 talentRank);
- void LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRank);
+ bool LearnTalent(uint32 talentId);
bool AddTalent(uint32 spellId, uint8 spec, bool learning);
bool HasTalent(uint32 spell_id, uint8 spec) const;
- uint32 CalculateTalentsPoints() const;
// Dual Spec
void UpdateSpecCount(uint8 count);
diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp
index 81a1ae73832..54956e591b4 100644
--- a/src/server/game/Entities/Totem/Totem.cpp
+++ b/src/server/game/Entities/Totem/Totem.cpp
@@ -67,7 +67,7 @@ void Totem::InitStats(uint32 duration)
GetOwner()->ToPlayer()->SendDirectMessage(&data);
// set display id depending on caster's race
- SetDisplayId(GetOwner()->GetModelForTotem(PlayerTotemType(m_Properties->Id)));
+ SetDisplayId(GetOwner()->GetModelForTotem(PlayerTotemType(m_Properties->ID)));
}
Minion::InitStats(duration);
@@ -91,7 +91,7 @@ void Totem::InitSummon()
if (GetSpell(1))
CastSpell(this, GetSpell(1), true);
- if (m_Properties->Id == SUMMON_TYPE_TOTEM_FIRE && GetOwner()->HasAura(SPELL_TOTEMIC_WRATH_TALENT))
+ if (m_Properties->ID == SUMMON_TYPE_TOTEM_FIRE && GetOwner()->HasAura(SPELL_TOTEMIC_WRATH_TALENT))
CastSpell(this, SPELL_TOTEMIC_WRATH, true);
}
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index b832292d89b..37b4d4d97a0 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -526,16 +526,16 @@ void Player::UpdateMastery()
value += GetRatingBonusValue(CR_MASTERY);
SetFloatValue(PLAYER_MASTERY, value);
- TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec()));
- if (!talentTab)
+ ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(GetTalentSpec(GetActiveSpec()));
+ if (!chrSpec)
return;
for (uint32 i = 0; i < MAX_MASTERY_SPELLS; ++i)
{
- if (!talentTab->MasterySpellId[i])
+ if (!chrSpec->MasterySpellID[i])
continue;
- if (Aura* aura = GetAura(talentTab->MasterySpellId[i]))
+ if (Aura* aura = GetAura(chrSpec->MasterySpellID[i]))
{
for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 49b9c2c45ae..70f8eb4d0fa 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -4301,13 +4301,6 @@ void ObjectMgr::LoadQuests()
qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
qinfo->RewardSpell = 0; // no spell reward will display for this quest
}
-
- else if (GetTalentSpellCost(qinfo->RewardSpell))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell);
- qinfo->RewardSpell = 0; // no spell reward will display for this quest
- }
}
if (qinfo->RewardSpellCast > 0)
@@ -4327,13 +4320,6 @@ void ObjectMgr::LoadQuests()
qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
qinfo->RewardSpellCast = 0; // no spell will be cast on player
}
-
- else if (GetTalentSpellCost(qinfo->RewardSpellCast))
- {
- TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.",
- qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast);
- qinfo->RewardSpellCast = 0; // no spell will be cast on player
- }
}
if (qinfo->RewardMailTemplateId)
@@ -8134,12 +8120,6 @@ void ObjectMgr::AddSpellToTrainer(uint32 ID, uint32 SpellID, uint32 MoneyCost, u
return;
}
- if (GetTalentSpellCost(SpellID))
- {
- TC_LOG_ERROR("sql.sql", "Table `npc_trainer` contains an ID (%u) for a non-existing spell (Spell: %u) which is a talent, ignoring", ID, SpellID);
- return;
- }
-
TrainerSpellData& data = _cacheTrainerSpellStore[ID];
TrainerSpell& trainerSpell = data.spellList[SpellID];
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 180e9bae74c..699d91c4cc9 100644
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -853,6 +853,7 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec
void WorldSession::HandlePetLearnTalent(WorldPacket& recvData)
{
+ /* TODO: 6.x remove pet talents (add pet specializations)
TC_LOG_DEBUG("network", "WORLD: CMSG_PET_LEARN_TALENT");
ObjectGuid guid;
@@ -860,11 +861,12 @@ void WorldSession::HandlePetLearnTalent(WorldPacket& recvData)
recvData >> guid >> talentId >> requestedRank;
_player->LearnPetTalent(guid, talentId, requestedRank);
- _player->SendTalentsInfoData(true);
+ _player->SendTalentsInfoData(true);*/
}
void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket& recvData)
{
+ /* TODO: 6.x remove pet talents (add pet specializations)
TC_LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS_PET");
ObjectGuid guid;
@@ -887,5 +889,5 @@ void WorldSession::HandleLearnPreviewTalentsPet(WorldPacket& recvData)
_player->SendTalentsInfoData(true);
- recvData.rfinish();
+ recvData.rfinish();*/
}
diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index 61868a8616a..c3f9dfc2868 100644
--- a/src/server/game/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
@@ -29,15 +29,17 @@
void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData)
{
+ /* TODO: 6.x update packet struct (note: LearnTalent no longer has rank argument)
uint32 talentId, requestedRank;
recvData >> talentId >> requestedRank;
if (_player->LearnTalent(talentId, requestedRank))
- _player->SendTalentsInfoData(false);
+ _player->SendTalentsInfoData(false);*/
}
void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
{
+ /* TODO: 6.x update packet struct
TC_LOG_DEBUG("network", "CMSG_LEARN_PREVIEW_TALENTS");
int32 tabPage;
@@ -77,7 +79,7 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
_player->SendTalentsInfoData(false);
- recvPacket.rfinish();
+ recvPacket.rfinish();*/
}
void WorldSession::HandleTalentWipeConfirmOpcode(WorldPacket& recvData)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index c383ba0d51f..c3ba18cad2c 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -2049,7 +2049,7 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
// however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
// and in spell attributes, possibly we need to add a table for those)
// so here's a list of MiscValueB values, which is currently most generic check
- switch (properties->Id)
+ switch (properties->ID)
{
case 64:
case 61:
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 9fc99e431d3..8bef55128c4 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -1478,9 +1478,10 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const
{
// talents that learn spells can have stance requirements that need ignore
// (this requirement only for client-side stance show in talent description)
+ /* TODO: 6.x fix this in proper way (probably spell flags/attributes?)
if (GetTalentSpellCost(Id) > 0 &&
(Effects[0].Effect == SPELL_EFFECT_LEARN_SPELL || Effects[1].Effect == SPELL_EFFECT_LEARN_SPELL || Effects[2].Effect == SPELL_EFFECT_LEARN_SPELL))
- return SPELL_CAST_OK;
+ return SPELL_CAST_OK;*/
uint32 stanceMask = (form ? 1 << (form - 1) : 0);
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index b3f2f283c4c..2c5d5c76bbe 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -1227,6 +1227,7 @@ void SpellMgr::UnloadSpellInfoChains()
void SpellMgr::LoadSpellTalentRanks()
{
+ /* TODO: 6.x remove this
// cleanup core data before reload - remove reference to ChainNode from SpellInfo
UnloadSpellInfoChains();
@@ -1283,7 +1284,7 @@ void SpellMgr::LoadSpellTalentRanks()
prevSpell = currentSpell;
}
- }
+ }*/
}
void SpellMgr::LoadSpellRanks()
@@ -1538,7 +1539,7 @@ void SpellMgr::LoadSpellLearnSpells()
continue;
}
- if (GetTalentSpellCost(node.spell))
+ if (GetTalentBySpellID(node.spell))
{
TC_LOG_ERROR("sql.sql", "Spell %u listed in `spell_learn_spell` attempt learning talent spell %u, skipped", spell_id, node.spell);
continue;
@@ -1576,7 +1577,7 @@ void SpellMgr::LoadSpellLearnSpells()
// talent or passive spells or skill-step spells auto-cast and not need dependent learning,
// pet teaching spells must not be dependent learning (cast)
// other required explicit dependent learning
- dbc_node.autoLearned = entry->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentSpellCost(spell) > 0 || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
+ dbc_node.autoLearned = entry->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET || GetTalentBySpellID(spell) || entry->IsPassive() || entry->HasEffect(SPELL_EFFECT_SKILL_STEP);
SpellLearnSpellMapBounds db_node_bounds = dbSpellLearnSpells.equal_range(spell);
@@ -1602,22 +1603,22 @@ void SpellMgr::LoadSpellLearnSpells()
}
uint32 mastery_count = 0;
- for (uint32 i = 0; i < sTalentTabStore.GetNumRows(); ++i)
+ for (uint32 i = 0; i < sChrSpecializationStore.GetNumRows(); ++i)
{
- TalentTabEntry const* talentTab = sTalentTabStore.LookupEntry(i);
- if (!talentTab)
+ ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(i);
+ if (!chrSpec)
continue;
for (uint32 c = CLASS_WARRIOR; c < MAX_CLASSES; ++c)
{
- if (!(talentTab->ClassMask & (1 << (c - 1))))
+ if (chrSpec->ClassID != c)
continue;
uint32 masteryMainSpell = MasterySpells[c];
for (uint32 m = 0; m < MAX_MASTERY_SPELLS; ++m)
{
- uint32 mastery = talentTab->MasterySpellId[m];
+ uint32 mastery = chrSpec->MasterySpellID[m];
if (!mastery)
continue;
diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
index 11ed54bfa81..a63a8ae6cdd 100644
--- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp
+++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp
@@ -128,7 +128,7 @@ void CharacterDatabaseCleaner::CleanCharacterSkills()
bool CharacterDatabaseCleaner::SpellCheck(uint32 spell_id)
{
- return sSpellMgr->GetSpellInfo(spell_id) && !GetTalentSpellPos(spell_id);
+ return sSpellMgr->GetSpellInfo(spell_id) && GetTalentBySpellID(spell_id) != nullptr;
}
void CharacterDatabaseCleaner::CleanCharacterSpell()
@@ -142,7 +142,7 @@ bool CharacterDatabaseCleaner::TalentCheck(uint32 talent_id)
if (!talentInfo)
return false;
- return sTalentTabStore.LookupEntry(talentInfo->TalentTab) != nullptr;
+ return sChrSpecializationStore.LookupEntry(talentInfo->SpecID) != nullptr;
}
void CharacterDatabaseCleaner::CleanCharacterTalent()
diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp
index eb5be0950aa..81499567b72 100644
--- a/src/server/scripts/Commands/cs_learn.cpp
+++ b/src/server/scripts/Commands/cs_learn.cpp
@@ -116,9 +116,6 @@ public:
else
targetPlayer->LearnSpell(spell, false);
- if (GetTalentSpellCost(spellInfo->GetFirstRankSpell()->Id))
- targetPlayer->SendTalentsInfoData(false);
-
return true;
}
@@ -176,10 +173,6 @@ public:
if (spellInfo->SpellFamilyName != family)
continue;
- // skip spells with first rank learned as talent (and all talents then also)
- if (GetTalentSpellCost(spellInfo->GetFirstRankSpell()->Id) > 0)
- continue;
-
// skip broken spells
if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
continue;
@@ -194,7 +187,7 @@ public:
static bool HandleLearnAllMyTalentsCommand(ChatHandler* handler, char const* /*args*/)
{
Player* player = handler->GetSession()->GetPlayer();
- uint32 classMask = player->getClassMask();
+ uint32 playerClass = player->getClass();
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
{
@@ -202,44 +195,25 @@ public:
if (!talentInfo)
continue;
- TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
- if (!talentTabInfo)
- continue;
-
- if ((classMask & talentTabInfo->ClassMask) == 0)
+ if (playerClass != talentInfo->ClassID)
continue;
- // search highest talent rank
- uint32 spellId = 0;
- for (int8 rank = MAX_TALENT_RANK - 1; rank >= 0; --rank)
- {
- if (talentInfo->RankID[rank] != 0)
- {
- spellId = talentInfo->RankID[rank];
- break;
- }
- }
-
- if (!spellId) // ??? none spells in talent
- continue;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(talentInfo->SpellID);
if (!spellInfo || !SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer(), false))
continue;
// learn highest rank of talent and learn all non-talent spell ranks (recursive by tree)
- player->LearnSpellHighestRank(spellId);
- player->AddTalent(spellId, player->GetActiveSpec(), true);
+ player->LearnSpellHighestRank(talentInfo->SpellID);
+ player->AddTalent(talentInfo->SpellID, player->GetActiveSpec(), true);
}
- player->SetFreeTalentPoints(0);
-
handler->SendSysMessage(LANG_COMMAND_LEARN_CLASS_TALENTS);
return true;
}
static bool HandleLearnAllMyPetTalentsCommand(ChatHandler* handler, char const* /*args*/)
{
+ /* TODO: 6.x remove pet talents
Player* player = handler->GetSession()->GetPlayer();
Pet* pet = player->GetPet();
@@ -312,7 +286,7 @@ public:
pet->SetFreeTalentPoints(0);
- handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);
+ handler->SendSysMessage(LANG_COMMAND_LEARN_PET_TALENTS);*/
return true;
}
@@ -484,9 +458,6 @@ public:
else
handler->SendSysMessage(LANG_FORGET_SPELL);
- if (GetTalentSpellCost(spellId))
- target->SendTalentsInfoData(false);
-
return true;
}
};
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 2a090aa70a8..deb714d1ef8 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -435,7 +435,7 @@ public:
handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, auras.size());
for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
- bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
+ bool talent = (GetTalentBySpellID(itr->second->GetBase()->GetId()) != nullptr);
AuraApplication const* aurApp = itr->second;
Aura const* aura = aurApp->GetBase();
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index 7d8fec52143..55468788d9f 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -812,15 +812,13 @@ public:
SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
- uint32 talentCost = GetTalentSpellCost(id);
-
- bool talent = (talentCost > 0);
+ bool talent = (GetTalentBySpellID(id) != nullptr);
bool passive = spellInfo->IsPassive();
bool active = target && target->HasAura(id);
// unit32 used to prevent interpreting uint8 as char at output
// find rank of learned spell for learning spell, or talent rank
- uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
+ uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
// send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
std::ostringstream ss;
@@ -884,15 +882,13 @@ public:
SpellInfo const* learnSpellInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[0].TriggerSpell);
- uint32 talentCost = GetTalentSpellCost(id);
-
- bool talent = (talentCost > 0);
+ bool talent = (GetTalentBySpellID(id) != nullptr);
bool passive = spellInfo->IsPassive();
bool active = target && target->HasAura(id);
// unit32 used to prevent interpreting uint8 as char at output
// find rank of learned spell for learning spell, or talent rank
- uint32 rank = talentCost ? talentCost : learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
+ uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
// send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
std::ostringstream ss;
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 24283dca7ac..d520c1cf765 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -419,6 +419,7 @@ public:
//Edit Player TP
static bool HandleModifyTalentCommand (ChatHandler* handler, const char* args)
{
+ /* TODO: 6.x remove this
if (!*args)
return false;
@@ -459,7 +460,7 @@ public:
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
- return false;
+ return false;*/
}
//Edit Player Aspeed
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 7049ad90a27..ed0709c6ad9 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -168,7 +168,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
Player* caster = GetCaster()->ToPlayer();
// No boomy, no deal.
- if (caster->GetPrimaryTalentTree(caster->GetActiveSpec()) != TALENT_TREE_DRUID_BALANCE)
+ if (caster->GetTalentSpec(caster->GetActiveSpec()) != TALENT_SPEC_DRUID_BALANCE)
return;
switch (GetSpellInfo()->Id)