aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/characters_database.sql2
-rw-r--r--sql/updates/characters/2012_01_29_00_characters_characters.sql (renamed from sql/updates/characters/2012_01_29_00_.characters_characters.sql)0
-rw-r--r--sql/updates/characters/2012_01_29_01_characters_characters.sql2
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp70
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h11
-rwxr-xr-xsrc/server/game/Server/Protocol/Handlers/SkillHandler.cpp2
6 files changed, 54 insertions, 33 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 5cd0db50dcb..df935c184d2 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -1127,7 +1127,7 @@ CREATE TABLE `characters` (
`rest_bonus` float NOT NULL DEFAULT '0',
`resettalents_cost` int(10) unsigned NOT NULL DEFAULT '0',
`resettalents_time` int(10) unsigned NOT NULL DEFAULT '0',
- `talentTree` smallint(5) unsigned NOT NULL DEFAULT '0',
+ `talentTree` varchar(10) NOT NULL DEFAULT '0 0',
`trans_x` float NOT NULL DEFAULT '0',
`trans_y` float NOT NULL DEFAULT '0',
`trans_z` float NOT NULL DEFAULT '0',
diff --git a/sql/updates/characters/2012_01_29_00_.characters_characters.sql b/sql/updates/characters/2012_01_29_00_characters_characters.sql
index baaf37ac467..baaf37ac467 100644
--- a/sql/updates/characters/2012_01_29_00_.characters_characters.sql
+++ b/sql/updates/characters/2012_01_29_00_characters_characters.sql
diff --git a/sql/updates/characters/2012_01_29_01_characters_characters.sql b/sql/updates/characters/2012_01_29_01_characters_characters.sql
new file mode 100644
index 00000000000..ae8aefc75b6
--- /dev/null
+++ b/sql/updates/characters/2012_01_29_01_characters_characters.sql
@@ -0,0 +1,2 @@
+ALTER TABLE `characters` CHANGE `talentTree` `talentTree` varchar(10) NOT NULL DEFAULT '0 0 ' AFTER `resettalents_time`;
+UPDATE `characters` SET `talentTree`='0 0 ';
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 22bd1846bb5..3140a3a8ef1 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -4528,7 +4528,7 @@ bool Player::ResetTalents(bool no_cost)
removeSpell(specSpells->at(i), true);
}
- SetPrimaryTalentTree(0);
+ SetPrimaryTalentTree(GetActiveSpec(), 0);
SetFreeTalentPoints(talentPointsForLevel);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
@@ -17146,11 +17146,18 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
}
// must be after loading spells and talents
- uint32 talentTree = uint32(fields[26].GetUInt16());
- if (sTalentTabStore.LookupEntry(talentTree))
- SetPrimaryTalentTree(talentTree);
- else
- SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents
+ Tokens talentTrees(fields[26].GetString(), ' ', MAX_TALENT_SPECS);
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ {
+ if (i >= talentTrees.size())
+ break;
+
+ uint32 talentTree = atol(talentTrees[i]);
+ if (sTalentTabStore.LookupEntry(talentTree))
+ SetPrimaryTalentTree(i, talentTree);
+ else if (i == GetActiveSpec())
+ SetAtLoginFlag(AT_LOGIN_RESET_TALENTS); // invalid tree, reset talents
+ }
sLog->outDebug(LOG_FILTER_PLAYER_LOADING, "The value of player %s after load item and aura is: ", m_name.c_str());
outDebugValues();
@@ -18528,7 +18535,11 @@ void Player::SaveToDB(bool create /*=false*/)
//save, but in tavern/city
stmt->setUInt32(index++, GetTalentResetCost());
stmt->setUInt32(index++, GetTalentResetTime());
- stmt->setUInt16(index++, uint16(GetPrimaryTalentTree()));
+
+ ss.str("");
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ ss << GetPrimaryTalentTree(i) << " ";
+ stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
stmt->setUInt16(index++, (uint16)m_atLoginFlags);
@@ -18635,7 +18646,11 @@ void Player::SaveToDB(bool create /*=false*/)
//save, but in tavern/city
stmt->setUInt32(index++, GetTalentResetCost());
stmt->setUInt32(index++, GetTalentResetTime());
- stmt->setUInt16(index++, uint16(GetPrimaryTalentTree()));
+
+ ss.str("");
+ for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
+ ss << GetPrimaryTalentTree(i) << " ";
+ stmt->setString(index++, ss.str());
stmt->setUInt16(index++, (uint16)m_ExtraFlags);
stmt->setUInt8(index++, m_stableSlots);
stmt->setUInt16(index++, (uint16)m_atLoginFlags);
@@ -23921,7 +23936,7 @@ bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
uint32 spentPoints = 0;
uint32 primaryTreeTalents = 0;
uint32 tTab = talentInfo->TalentTab;
- bool isMainTree = GetPrimaryTalentTree() == tTab || !GetPrimaryTalentTree();
+ bool isMainTree = GetPrimaryTalentTree(GetActiveSpec()) == tTab || !GetPrimaryTalentTree(GetActiveSpec());
if (talentInfo->Row > 0 || !isMainTree)
{
@@ -23937,7 +23952,7 @@ bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
{
if (tmpTalent->TalentTab == tTab)
spentPoints += (rank + 1);
- if (tmpTalent->TalentTab == GetPrimaryTalentTree())
+ if (tmpTalent->TalentTab == GetPrimaryTalentTree(GetActiveSpec()))
primaryTreeTalents += (rank + 1);
}
}
@@ -23973,9 +23988,9 @@ bool Player::LearnTalent(uint32 talentId, uint32 talentRank)
sLog->outDetail("TalentID: %u Rank: %u Spell: %u Spec: %u\n", talentId, talentRank, spellid, GetActiveSpec());
// set talent tree for player
- if (!GetPrimaryTalentTree())
+ if (!GetPrimaryTalentTree(GetActiveSpec()))
{
- SetPrimaryTalentTree(talentInfo->TalentTab);
+ SetPrimaryTalentTree(GetActiveSpec(), talentInfo->TalentTab);
std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(talentInfo->TalentTab);
if (specSpells)
for (size_t i = 0; i < specSpells->size(); ++i)
@@ -24198,7 +24213,6 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
// loop through all specs (only 1 for now)
for (uint32 specIdx = 0; specIdx < GetSpecsCount(); ++specIdx)
{
- size_t specPos = data->wpos();
*data << uint32(0);
uint8 talentIdCount = 0;
size_t pos = data->wpos();
@@ -24240,23 +24254,10 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
*data << uint32(talentInfo->TalentID); // Talent.dbc
*data << uint8(curtalent_maxrank); // talentMaxRank (0-4)
- talentCounts[i] += curtalent_maxrank + 1;
++talentIdCount;
}
}
- if (talentIdCount)
- {
- uint32 maxTalentsSpec = 0;
- if (talentCounts[1] > talentCounts[maxTalentsSpec])
- maxTalentsSpec = 1;
-
- if (talentCounts[2] > talentCounts[maxTalentsSpec])
- maxTalentsSpec = 2;
-
- data->put<uint32>(specPos, talentTabIds[maxTalentsSpec]);
- }
-
data->put<uint8>(pos, talentIdCount); // put real count
*data << uint8(MAX_GLYPH_SLOT_INDEX); // glyphs count
@@ -24752,6 +24753,15 @@ void Player::ActivateSpec(uint8 spec)
}
}
+ // Remove spec specific spells
+ for (uint32 i = 0; i < MAX_TALENT_TABS; ++i)
+ {
+ std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetTalentTabPages(getClass())[i]);
+ if (specSpells)
+ for (size_t i = 0; i < specSpells->size(); ++i)
+ removeSpell(specSpells->at(i), true);
+ }
+
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
// remove secondary glyph
@@ -24793,6 +24803,11 @@ void Player::ActivateSpec(uint8 spec)
}
}
+ std::vector<uint32> const* specSpells = GetTalentTreePrimarySpells(GetPrimaryTalentTree(GetActiveSpec()));
+ if (specSpells)
+ for (size_t i = 0; i < specSpells->size(); ++i)
+ learnSpell(specSpells->at(i), false);
+
// set glyphs
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
{
@@ -24824,6 +24839,9 @@ void Player::ActivateSpec(uint8 spec)
SetPower(POWER_MANA, 0); // Mana must be 0 even if it isn't the active power type.
SetPower(pw, 0);
+
+ if (!sTalentTabStore.LookupEntry(GetPrimaryTalentTree(GetActiveSpec())))
+ ResetTalents(true);
}
void Player::ResetTimeSync()
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 73c8c010e76..9ac5f221b48 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1090,13 +1090,14 @@ struct PlayerTalentInfo
{
PlayerTalentInfo() :
FreeTalentPoints(0), UsedTalentCount(0), QuestRewardedTalentCount(0),
- ResetTalentsCost(0), ResetTalentsTime(0), TalentTree(0),
+ ResetTalentsCost(0), ResetTalentsTime(0),
ActiveSpec(0), SpecsCount(1)
{
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
- memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
SpecInfo[i].Talents = new PlayerTalentMap();
+ memset(SpecInfo[i].Glyphs, 0, MAX_GLYPH_SLOT_INDEX * sizeof(uint32));
+ SpecInfo[i].TalentTree = 0;
}
}
@@ -1114,6 +1115,7 @@ struct PlayerTalentInfo
{
PlayerTalentMap* Talents;
uint32 Glyphs[MAX_GLYPH_SLOT_INDEX];
+ uint32 TalentTree;
} SpecInfo[MAX_TALENT_SPECS];
uint32 FreeTalentPoints;
@@ -1121,7 +1123,6 @@ struct PlayerTalentInfo
uint32 QuestRewardedTalentCount;
uint32 ResetTalentsCost;
time_t ResetTalentsTime;
- uint32 TalentTree;
uint8 ActiveSpec;
uint8 SpecsCount;
@@ -1738,8 +1739,8 @@ class Player : public Unit, public GridObject<Player>
void SetTalentResetCost(uint32 cost) { _talentMgr->ResetTalentsCost = cost; }
uint32 GetTalentResetTime() const { return _talentMgr->ResetTalentsTime; }
void SetTalentResetTime(time_t time_) { _talentMgr->ResetTalentsTime = time_; }
- uint32 GetPrimaryTalentTree() const { return _talentMgr->TalentTree; }
- void SetPrimaryTalentTree(uint32 tree) { _talentMgr->TalentTree = tree; }
+ 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; }
diff --git a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp b/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp
index 09d8b42c0ab..2e4ef5cb40d 100755
--- a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp
+++ b/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp
@@ -46,7 +46,7 @@ void WorldSession::HandleLearnPreviewTalents(WorldPacket& recvPacket)
// prevent cheating (selecting new tree with points already in another)
if (tabPage >= 0) // -1 if player already has specialization
{
- if (TalentTabEntry const* talentTabEntry = sTalentTabStore.LookupEntry(_player->GetPrimaryTalentTree()))
+ if (TalentTabEntry const* talentTabEntry = sTalentTabStore.LookupEntry(_player->GetPrimaryTalentTree(_player->GetActiveSpec())))
{
if (talentTabEntry->tabpage != tabPage)
{