diff options
-rw-r--r-- | sql/base/characters_database.sql | 2 | ||||
-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.sql | 2 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 70 | ||||
-rwxr-xr-x | src/server/game/Entities/Player/Player.h | 11 | ||||
-rwxr-xr-x | src/server/game/Server/Protocol/Handlers/SkillHandler.cpp | 2 |
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) { |